我们有时在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

10-06 14:32