MVC 5 Viewmodel 绑定有效,但 post 背面已部分填充
MVC 5 Viewmodel binding works but post back is partial filled
我为 HttpGet
设置了一个无参数的 Index
,它可以工作。但是当我 post 它调用 Index
的 HttpPost
版本并传入视图模型 object 时,但其中只有下拉列表的值。其余为空(产品,标题)
[HttpPost]
public ActionResult Index(ProductsViewModel pvm)
{
// breakpoint on line 36, shows that pvm.Title is null and Products too.
return View(pvm);
}
我的可编译和 运行 示例可以从我的 OneDrive 下载 http://1drv.ms/1zSsMkr
我的看法:
@model KleinKloteProductOverzicht.Models.ProductsViewModel
@using (Html.BeginForm("Index", "Products"))
{
<h2>@Html.DisplayFor(m => m.Title)</h2>
<input type="submit" value="post dit" /><br/>
<div class="row">
<div class="col-lg-2 col-md-2">
@Html.DropDownListFor(x => x.CurrentSort, EnumHelper.GetSelectList(typeof(SortOptions)), new { @class = "multiselect"})
</div>
</div>
if (Model.Products.Count() > 0)
{
<div class="row">
@foreach (var item in Model.Products)
{
@Html.DisplayFor(i => item.Name);
}
</div>
}
}
如果我有这个视图模型:
public class ViewModel
{
public string Name {get;set;}
public string SelectedLocation {get;set;}
public IEnumerable<SelectListItem> Locations {get;set;}
}
你的动作是这样的:
public ActionResult MyForm()
{
var vm = new ViewModel
{
Locations = context.Locations.ToList() // Some database call
}
return View(vm);
}
[HttpPost]
public ActionResult MyForm(ViewModel vm)
{
vm.Locations // this is null
}
这是null
,因为模型绑定器找不到正在设置其数据的表单控件。
<form>
必须在视图中设置一些数据,以便模型绑定器提取它。
<form>
Name: <input type="text" id="name" />
</form>
这将在视图模型上设置 Name
属性,因为模型绑定可以看到表单控件的 id
并使用它来知道绑定到什么。
因此,就您的观点而言,您需要确保使用 @using(Html.BeginForm())
包装您想要 post 返回服务器的任何内容
反正这是我的猜测。
嗯,您似乎对 [HttpPost] 和表单标签如何相互交互感到困惑。
您会看到,当 .NET MVC 在您的控制器操作中绑定您的参数时,它会尝试从请求中派生该数据。对于 [HttpGet],它通过查看查询字符串来完成此操作。
对于 [HttpPost] 调用,它还会查看 Request.Form。此变量填充了您提交的表单中所有输入字段的值。
现在,这是您的观点:
@using (Html.BeginForm("Index", "Products"))
{
<h2>@Html.DisplayFor(m => m.Title)</h2>
<input type="submit" value="post dit" /><br/>
<div class="row">
<div class="col-lg-2 col-md-2">
@Html.DropDownListFor(x => x.CurrentSort, EnumHelper.GetSelectList(typeof(SortOptions)), new { @class = "multiselect" })
</div>
</div>
if (Model.Products.Count() > 0)
{
<div class="row">
@foreach (var item in Model.Products)
{
@Html.DisplayFor(i => item.Name);
}
</div>
}
}
您只有一个 select
标签(由 Dropdownlistfor 生成)但没有其他输入。这就是 .NET MVC 无法为您的视图模型推断任何其他数据的原因。
如果你改变你的看法:
@model KleinKloteProductOverzicht.Models.ProductsViewModel
@using (Html.BeginForm("Index", "Products"))
{
<h2>@Html.DisplayFor(m => m.Title)</h2>
<input type="submit" value="post dit" /><br/>
<div class="row">
<div class="col-lg-2 col-md-2">
@Html.DropDownListFor(x => x.CurrentSort, EnumHelper.GetSelectList(typeof(SortOptions)), new { @class = "multiselect" })
</div>
</div>
if (Model.Products.Count() > 0)
{
<div class="row">
@for (var i = 0; i < Model.Products.Count; i++)
{
@Html.DisplayFor(model => model.Products[i].Name)
@Html.HiddenFor(model => model.Products[i].ID)
}
</div>
}
}
您会看到我为产品 ID 添加了隐藏输入 (<input type="hidden">
)。请注意,产品名称仍然为空。
我建议您遵循有关 .NET MVC 的教程并阅读其背后的一些概念,因为您问这个问题这一事实表明您还有很多东西要学。
祝你好运!
P.S。最后一个提示:@Html.Blablabla
直接写入您的视图。你通常不需要那个“;”最后,因为它将在您生成的 html 中。
您的 属性 未与 "postable" 控件相关联,因此它不会与表单数据一起提交。如果您真的想在 Title
属性 中获取值,只需将其设置为隐藏输入即可。
@Html.HiddenFor(m => m.Title)
提交 form
时不会发布 label
,但会发布 input
。这正是 HiddenFor
所做的;它创建了一个隐藏的 input
元素,该元素将被 form
提交拾取。
我为 HttpGet
设置了一个无参数的 Index
,它可以工作。但是当我 post 它调用 Index
的 HttpPost
版本并传入视图模型 object 时,但其中只有下拉列表的值。其余为空(产品,标题)
[HttpPost]
public ActionResult Index(ProductsViewModel pvm)
{
// breakpoint on line 36, shows that pvm.Title is null and Products too.
return View(pvm);
}
我的可编译和 运行 示例可以从我的 OneDrive 下载 http://1drv.ms/1zSsMkr
我的看法:
@model KleinKloteProductOverzicht.Models.ProductsViewModel
@using (Html.BeginForm("Index", "Products"))
{
<h2>@Html.DisplayFor(m => m.Title)</h2>
<input type="submit" value="post dit" /><br/>
<div class="row">
<div class="col-lg-2 col-md-2">
@Html.DropDownListFor(x => x.CurrentSort, EnumHelper.GetSelectList(typeof(SortOptions)), new { @class = "multiselect"})
</div>
</div>
if (Model.Products.Count() > 0)
{
<div class="row">
@foreach (var item in Model.Products)
{
@Html.DisplayFor(i => item.Name);
}
</div>
}
}
如果我有这个视图模型:
public class ViewModel
{
public string Name {get;set;}
public string SelectedLocation {get;set;}
public IEnumerable<SelectListItem> Locations {get;set;}
}
你的动作是这样的:
public ActionResult MyForm()
{
var vm = new ViewModel
{
Locations = context.Locations.ToList() // Some database call
}
return View(vm);
}
[HttpPost]
public ActionResult MyForm(ViewModel vm)
{
vm.Locations // this is null
}
这是null
,因为模型绑定器找不到正在设置其数据的表单控件。
<form>
必须在视图中设置一些数据,以便模型绑定器提取它。
<form>
Name: <input type="text" id="name" />
</form>
这将在视图模型上设置 Name
属性,因为模型绑定可以看到表单控件的 id
并使用它来知道绑定到什么。
因此,就您的观点而言,您需要确保使用 @using(Html.BeginForm())
反正这是我的猜测。
嗯,您似乎对 [HttpPost] 和表单标签如何相互交互感到困惑。
您会看到,当 .NET MVC 在您的控制器操作中绑定您的参数时,它会尝试从请求中派生该数据。对于 [HttpGet],它通过查看查询字符串来完成此操作。
对于 [HttpPost] 调用,它还会查看 Request.Form。此变量填充了您提交的表单中所有输入字段的值。
现在,这是您的观点:
@using (Html.BeginForm("Index", "Products"))
{
<h2>@Html.DisplayFor(m => m.Title)</h2>
<input type="submit" value="post dit" /><br/>
<div class="row">
<div class="col-lg-2 col-md-2">
@Html.DropDownListFor(x => x.CurrentSort, EnumHelper.GetSelectList(typeof(SortOptions)), new { @class = "multiselect" })
</div>
</div>
if (Model.Products.Count() > 0)
{
<div class="row">
@foreach (var item in Model.Products)
{
@Html.DisplayFor(i => item.Name);
}
</div>
}
}
您只有一个 select
标签(由 Dropdownlistfor 生成)但没有其他输入。这就是 .NET MVC 无法为您的视图模型推断任何其他数据的原因。
如果你改变你的看法:
@model KleinKloteProductOverzicht.Models.ProductsViewModel
@using (Html.BeginForm("Index", "Products"))
{
<h2>@Html.DisplayFor(m => m.Title)</h2>
<input type="submit" value="post dit" /><br/>
<div class="row">
<div class="col-lg-2 col-md-2">
@Html.DropDownListFor(x => x.CurrentSort, EnumHelper.GetSelectList(typeof(SortOptions)), new { @class = "multiselect" })
</div>
</div>
if (Model.Products.Count() > 0)
{
<div class="row">
@for (var i = 0; i < Model.Products.Count; i++)
{
@Html.DisplayFor(model => model.Products[i].Name)
@Html.HiddenFor(model => model.Products[i].ID)
}
</div>
}
}
您会看到我为产品 ID 添加了隐藏输入 (<input type="hidden">
)。请注意,产品名称仍然为空。
我建议您遵循有关 .NET MVC 的教程并阅读其背后的一些概念,因为您问这个问题这一事实表明您还有很多东西要学。
祝你好运!
P.S。最后一个提示:@Html.Blablabla
直接写入您的视图。你通常不需要那个“;”最后,因为它将在您生成的 html 中。
您的 属性 未与 "postable" 控件相关联,因此它不会与表单数据一起提交。如果您真的想在 Title
属性 中获取值,只需将其设置为隐藏输入即可。
@Html.HiddenFor(m => m.Title)
提交 form
时不会发布 label
,但会发布 input
。这正是 HiddenFor
所做的;它创建了一个隐藏的 input
元素,该元素将被 form
提交拾取。