我们有时在MVC3中遇到Html.HiddenFor问题,有时无法正确绑定。我们根本无法重现它,但是我们看到日志中通过了nullref,这绝对使我们发疯。
我们具有以下模型和控制器结构:
public class DummyController
{
[HttpGet]
public ActionResult ReturnAPage(int NumericID)
{
//NumericID should never be 0 or negative, but let's check to make sure
if (NumericID < 1)
{
return RedirectToAction("TracyJordanStabbingRobot");
}
return View("DummyView", new DummyViewModel(NumericID));
}
[HttpPost]
public ActionResult TakePageSubmission(DummyViewModel model)
{
//AnObject relies on having a non-zero ID
ComplexObject AnObject = new ComplexObject(model.NumericID);
AnObject.UseMe();
}
}
public class DummyViewModel
{
public DummyViewModel() {}
public DummyViewModel(int ID)
{
NumericID = ID;
}
public int NumericID { get; set; }
}
...以及以下视图结构:
DummyView.cshtml
@model DummyViewModel
<html>
<head></head>
<body>
<p>THIS IS A VIEW!</p>
<form id="DummyViewForm" action="/RouteTo/TakePageSubmission" method="post">
@Html.Partial("_PartialDummyView", Model)
<input type="submit" value="Submit This!" />
</form>
</body>
</html>
_PartialDummyView.cshtml
@model DummyViewModel
<p>Heard you like views...</p>
@Html.HiddenFor(model => model.NumericID)
考虑到我们正在初始控制器操作中检查小于零的值,因此可以推断
@Html.HiddenFor(model => model.NumericID)
永远不应小于零。话虽这么说,当我们在
AnObject
动作中使用TakePageSubmission
时,我们得到的是空引用错误。当我们探究记录
model.NumericID
值时,我们看到它以零表示,考虑到DummyView只能使用非零值访问,因此这不可能。我们有些困惑,并且由于我们无法可靠地重现该问题,因此我们不知道可能是什么原因引起的。有人遇到过这样的事情吗?
编辑:我们正在表单发布中进行ModelState验证,但是我们没有检查是否通过的NumericID为0。当我们进行检查时,模型通过为无效,这只是证明HiddenFor正在获取设置不正确。此外,到页面的路由实际上包括NumericID,因此,例如,我们已经看到这种情况:
http://our.site.com/RouteToReturnAPage/1736/
...在明确设置操作参数的位置,可以正确构造模型,但是由于某些未知原因,HiddenFor NumericID值为0。这确实令人困惑。
最佳答案
您的默认0值绑定是在发布后从MVC视图到同一页面,因为您认为由于发布期间发生错误,它正在重新加载同一视图。正确的绑定将发生在对另一个Action调用的load / action调用上。
在重新加载View之前,有一个针对ModelState.Clear();
的黑客解决方法。
另外,根本不使用帮助程序来创建隐藏字段,例如:
<input type="hidden" value="@Model.NumericID" id="NumericID" name="NumericID" />
参考:
http://blogs.msdn.com/b/simonince/archive/2010/05/05/asp-net-mvc-s-html-helpers-render-the-wrong-value.aspx