【问题标题】:ASP.NET MVC 3 - Best practice for handling Model in ViewASP.NET MVC 3 - 在视图中处理模型的最佳实践
【发布时间】:2011-07-06 14:35:45
【问题描述】:

我正在使用 ASP.NET MVC 3 并且有几个页面,其中大部分视图模型都是只读的。示例字段如下所示:

<div class="display-label">My Field</div>
<div class="display-field">@Model.MyField</div>

然后我有一个字段,用户必须在其中输入一些验证文本,如下所示:

@Html.LabelFor(model => model.Verification)
@Html.PasswordFor(model => model.Verification)

当用户提交表单并点击我的控制器时,除了 Verification 字段之外,ViewModel 的字段都为空。到目前为止,我解决这个问题的方法是有几个像这样的 HiddenFor 字段:

@Html.HiddenFor(model => model.MyField)

但是,这很快就会变得丑陋。有没有更好的方法来处理视图状态下的模型,以便在表单提交的 POST 期间,我可以获得所有字段?这在 POST 期间验证文本不匹配并且我需要返回视图模型而不从数据库中重新检索它的情况下很重要。

感谢您的任何建议。

【问题讨论】:

    标签: c# .net asp.net-mvc asp.net-mvc-3 viewstate


    【解决方案1】:

    如果不从数据库中重新检索值,没有更好的解决方法。原因是因为 MVC 的模型绑定只查看 GET 或 POST 参数以将 MyField 绑定到操作的模型,如果 GET/POST 参数没有 MyField 值,那么它必须将该属性保留为null(否则它怎么知道值应该是什么?)

    为了让模型绑定器看到您的MyField 值,请将其传递到 GET/POST 参数中,为此您必须明确告诉视图的表单通过 Html.HiddenFor() 传递值。视图无法自动知道在 post/get 参数中发送该属性。

    然而您可以考虑创建一个 Razor(或 Html)辅助方法,该方法采用字段名称和表达式(x =&gt; x.MyField)并为您编写以下输出:

    <div class="display-label">My Field</div>
    <div class="display-field">@Model.MyField</div>
    @Html.HiddenFor(model => model.MyField)
    

    这意味着您只需编写一行代码(类似于@Html.ShowReadOnlyField(x =&gt; x.MyField, "My Field") 而不是那 3 行代码。但是,这也假设您要执行此操作的任何地方都具有相同的 div 结构。

    编辑:请记住有关只读字段的安全问题,因为它们并不是真正的只读字段。如果出现这种情况,最好从数据库中重新检索此数据data 将用于控制器中的任何内容,因为即使它在 HTML 表单上是只读的,用户仍然可以通过操作 POST/GET 数据将此值设置为他们想要的任何值。

    【讨论】:

    • 您能否通过使用帮助程序@Html.AntiForgeryToken() 来解决安全问题?
    • 我对此表示怀疑。我不太了解 AntiForgeryToken 功能,但很可能用户可以查看页面的源代码以了解他们需要提供什么令牌才能使其正常工作。伪造令牌更多地用于跨站点脚本攻击,而不是用于价值保护,现在它可以知道是否要提供一个字段。任何本应安全的事情都需要在服务器端进行处理,并且您不能依赖客户端功能来确保安全
    • 我最终只是在控制器中重新加载了我的对象实例。
    【解决方案2】:

    请尝试序列化页面中的模型,然后进行发布?这应该可以解决问题。

    <%= Html.Serialize("User",Model) %>
    
    [HttpPost]   
    public ActionResult Register([DeserializeAttribute] User user, FormCollection userForm)
    {
    
    }
    

    【讨论】:

      猜你喜欢
      • 2011-09-16
      • 2011-04-08
      • 2016-06-06
      • 1970-01-01
      • 2012-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多