3

我们在 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)应该有小于零的值。

话虽如此,当我们开始AnObjectTakePageSubmission操作中使用时,我们会得到空引用错误。

当我们深入记录该model.NumericID值时,我们看到它为零,考虑到 DummyView 只能使用非零值访问,这应该是不可能的。

我们有点难过,因为我们无法可靠地重现这个问题,我们知道是什么原因造成的。有没有人遇到过这样的事情?

编辑:我们正在表单帖子上进行 ModelState 验证,但我们没有检查通过的 NumericID 是否为 0。当我们检查时,模型通过无效,这只是证明 HiddenFor 正在获取设置不当。此外,到页面的路由实际上包括NumericID,例如,我们已经看到这种情况发生在:

http://our.site.com/RouteToReturnAPage/1736/

...在明确设置动作参数的情况下,模型构造正确,但由于某种未知原因,HiddenFor NumericID 值为 0。这真的令人费解。

4

2 回答 2

3

您的默认 0 值绑定是在发布后从 MVC 查看到同一页面,认为由于发布期间的错误而重新加载相同的视图。正确的绑定将在加载/操作调用到不同的操作调用时发生。

ModelState.Clear();在重新加载视图之前,有一个 hack 解决方法。

此外,根本不使用 Helpers 创建隐藏字段,例如:

<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

于 2013-05-15T04:23:28.023 回答
0

First you are missing default constructor in your model. Without it applicaiton throws exception when binding.

You can reproduce the error by editing the hidden field on client side. So user can change id to 0 or any other value. If you aren't running you application on distributed enviroment then use TempData to pass the id between actions. This way you will keep id safe from data tampering.

TempData["NumericID"] = NumericID;
于 2013-03-23T07:32:48.687 回答