使用来自AJAX调用的响应填充div时,@ Html.Hidden的值不正确

我有一个简单的视图,其中包含一个div ,其中包含部分视图。 部分视图包含项目列表。 每个项目都显示在排除状态(标记为XXX)或显示一个按钮以排除项目(使用Ajax.BeginForm )提交Id并更新其状态并重绘列表。

首次绘制页面时,它可以正常工作,但是当在Ajax调用之后重新呈现局部视图以排除项目时,而不是列表中具有唯一itemId每个项目都具有该项目的itemId由表单提交排除。

Index.cshtml(主视图)

 @model IEnumerable 
@Html.Partial("ItemList", Model)
@section Scripts { @Scripts.Render("~/bundles/jqueryval") }

ItemList.cshtml(部分视图)

 @model IEnumerable 
    @foreach (var item in Model) {
  • @if(item.Excluded) { } else { using (Ajax.BeginForm("ExcludeItem", new AjaxOptions { HttpMethod = "post", InsertionMode = InsertionMode.Replace, UpdateTargetId = "modelList" })) { @Html.Hidden("id", item.Id) <!-- --> } }
  • }

我可以通过注释掉@Html.Hidden并取消注释隐藏的输入来使页面工作(在这种情况下,正确的值设置为项目的id)。

这里发生了什么? 我使用Html.Hidden或Ajax表单的方式有问题吗? 或者它不应该在这种情况下工作?

HomeController.cs(以防它是相关的)

 public class TestModel { public int Id { get; set; } public string Name { get; set; } public bool Excluded { get; set; } } public class HomeController : Controller { static List _items = new List{ new TestModel { Id=1, Name="Item 1", Excluded=false }, new TestModel { Id=2, Name="Item 2", Excluded=false }, new TestModel { Id=3, Name="Item 3", Excluded=false }, new TestModel { Id=4, Name="Item 4", Excluded=false } }; public ActionResult Index() { return View(_items); } public ActionResult GetItems() { return PartialView("ItemList", _items); } [HttpPost] public ActionResult ExcludeItem(int id) { _items.Find(x=>x.Id == id).Excluded = true; return PartialView("ItemList", _items); } } 

示例输出,以帮助说明问题:

在页面加载时的modelList div

 
  • <!-- -->
  • <!-- -->
  • <!-- -->
  • <!-- -->

提交以排除第2项后的modelList(注意所有输入的值=“2”)

 
  • <!-- -->
  • <!-- -->
  • <!-- -->

问题是由于所有input元素具有相同的id / name(顺便说一下,具有相同id的多个元素导致无效的HTML),并且ASP.NET MVC基于以下方式重新绑定输入来自ModelState数据不是您的模型(这是默认使用的机制,用于返回用户输入的值的表单)。

要避免从ModelState绑定,只需在POST操作中清除它:

 [HttpPost] public ActionResult ExcludeItem(int id) { _items.Find(x=>x.Id == id).Excluded = true; ModelState.Clear(); return PartialView("ItemList", _items); } 

我还建议更改调用Html.Hidden ,以避免重复的id到这样的事情:

 @Html.Hidden("id", item.Id, new { @id = "id_" + item.Id }); 

这样你的输入应该像这样呈现:

  

这是完全有效的,仍然会正确绑定。