Html.HiddenFor绑定到错误元素

6

我有一个ASP.NET MVC应用程序,显示了一系列项目。在我的视图页面中,我循环遍历这些项目,并使用部分视图来呈现每个项目,如下所示:

@foreach(var item in Model.items)
{
   <li>
       @Html.Partial("ItemView", item)
   </li>
}

在项目视图中,我会用一个包含“删除”按钮的表单来包装每个项目,如下所示:
@using(Html.BeginForm(...))
{
    @Html.HiddenFor(m=>m.Id)
    <label>@Model.Name (@Model.Id)</label>
    <input type="submit" value="Delete"/>
}

项目已正确渲染,生成的页面展示了所有项目的名称和ID。编辑:与我之前写的相反,@Hidden也会发生同样的情况。
此外,这只会在表单第二次呈现时发生(即在点击删除按钮后),第一次一切正常。我的操作方法如下:
public ActionResult AllItems()
{
    var model = new AllItemsModel();
    return PartialView(model);
}

public ActionResult Delete(DeleteModel model)
{
    .... Perform the delete ...
    return PartialView("AllItems", new AllItemsModel());
}

为什么会发生这种情况?

1个回答

8

我怀疑这是因为您的RouteData中已经有了一个Id参数:


可能是因为您的RouteData中已经存在一个名为Id的参数。
public ActionResult SomeAction(int id)
{
    var model = ...
    return View(model);
}

您请求了带有/somecontroller/someaction/123的页面。 HiddenFor助手现在使用路由值中的Id而不是项目ID。尝试将项目视图模型上的属性重命名为与Id不同的其他名称,例如ItemId

另一个可能性是问题仅在POST回发后而不是初始呈现页面时才出现。显示您的POST操作可能有助于进一步探索这个可能性。


更新:

好吧,既然您已经展示了您的POST操作,事情现在更加清晰了:

public ActionResult Delete(DeleteModel model)
{
    .... Perform the delete ...
    return PartialView("AllItems", new AllItemsModel());
}

在这里,您基本上正在创建一个新的视图模型并将其传递给部分视图。但是HTML助手始终在绑定时使用ModelState中的值。只有在此之后才使用您的视图模型中的值。因此,如果您打算在POST操作中修改模型上的属性,请确保首先从ModelState中删除此值。在您的示例中,由于您已完全删除了整个视图模型(通过创建new AllItemsModel()),因此您可以清除整个ModelState:

public ActionResult Delete(DeleteModel model)
{
    .... Perform the delete ...

    // Clear the modelstate otherwise the view will use the values that were initially posted
    // and not the values from your view model
    ModelState.Clear();
    return PartialView("AllItems", new AllItemsModel());
}

这种行为是有意设计的,并适用于所有HTML辅助器,不仅适用于HiddenFor辅助器。


哇,非常好的观察。我会检查一下,我想我没有一个。 - zmbq
你的第一个建议不正确,但第二个看起来很有前途。太遗憾了我不能+1两次...我会检查它的。 - zmbq

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接