Html.Hidden偶尔没有设置w /模型信息

时间:2013-03-22 15:00:56

标签: asp.net-mvc razor model-binding

我们遇到的问题是MVC3 中的Html.HiddenFor偶尔无法正确绑定。我们根本无法重现它,但我们在日志记录中看到了nullrefs,这让我们绝对疯狂。

我们有以下模型和控制器结构:

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.这真是令人费解。

2 个答案:

答案 0 :(得分:3)

您的默认0值绑定是从发布后的MVC View'ing到同一页面,认为由于帖子中的错误而重新加载相同的视图。在对不同Action调用的加载/操作调用中将发生正确的绑定。

在重新加载视图之前,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

答案 1 :(得分:0)

首先,您缺少模型中的默认构造函数。如果没有它,应用程序会在绑定时抛出异常。

您可以通过编辑客户端的隐藏字段来重现错误。因此用户可以将id更改为0或任何其他值。如果您没有在分布式环境中运行应用程序,则使用TempData在操作之间传递id。通过这种方式,您可以确保id不被数据篡改。

TempData["NumericID"] = NumericID;