【问题标题】:Html.HiddenFor sporadically not getting set w/ model informationHtml.HiddenFor 偶尔没有设置带有模型信息
【发布时间】:2013-03-22 15:00:55
【问题描述】:

我们遇到了 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 =&gt; model.NumericID) 永远不应该有小于零的值。

话虽如此,当我们在TakePageSubmission 操作中使用AnObject 时,我们会遇到空引用错误。

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

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

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

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

...在明确设置动作参数的地方,模型构造正确,但由于某种未知原因,HiddenFor NumericID 的值为 0。真是莫名其妙。

【问题讨论】:

  • 是外部网站吗?会不会是有人在尝试一些不愉快的事情?还是蜘蛛什么的?
  • 会不会是你在RedirectToAction("TracyJordanStabbingRobot");前面少了一个return
  • @Liam 不,一切都在我们网站的控制范围内。
  • @Liam 这可能是原因。如果没有 HttpPost,我可以简单地转到 http://../Dummy/TakePageSubmission 并完全绕过表单提交。
  • 很抱歉继续编辑它 - 在生产中它实际上只标记为 w/ post。

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


【解决方案1】:

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

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

另外,根本不使用 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

【讨论】:

    【解决方案2】:

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

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

    TempData["NumericID"] = NumericID;
    

    【讨论】:

    • 抱歉,就像我说的那样,我输入的代码有些匆忙。有一个默认构造函数。
    猜你喜欢
    • 1970-01-01
    • 2015-04-14
    • 1970-01-01
    • 2018-11-21
    • 2019-03-06
    • 2014-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多