ASP.NET MVC 3 - 在视图中处理模型的最佳实践

5

我正在使用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)

当用户提交表单并到达我的控制器时,ViewModel的字段都是空的,除了Verification字段。到目前为止,我解决这个问题的方法是添加几个HiddenFor字段,如下所示:
@Html.HiddenFor(model => model.MyField)

然而,这很快变得混乱。有没有更好的方法来处理视图状态中的模型,以便在表单提交的POST期间,我可以获取所有字段?如果在POST期间验证文本不匹配并且我需要返回视图模型而无需从数据库重新检索它,则此功能非常重要。
感谢任何建议。
2个回答

3
没有更好的方法可以避免重新从数据库中获取值。原因是MVC的模型绑定只查看GET或POST参数来绑定MyField到操作的模型中,如果GET或POST参数没有MyField的值,那么它必须将该属性保持为null(否则它怎么知道该值应该是什么?)
为了使模型绑定器看到您的MyField值,需要通过GET/POST参数传递它,并且要执行此操作,必须明确告诉视图的表单通过Html.HiddenFor()传递该值。视图无法自动知道在POST / GET参数中发送该属性的方式。
然而,您可以考虑创建一个Razor(或Html)帮助程序方法,该方法采用字段名称和表达式(x=>x.MyField),并为您编写以下输出。
<div class="display-label">My Field</div>
<div class="display-field">@Model.MyField</div>
@Html.HiddenFor(model => model.MyField)

这意味着你只需要编写一行代码(类似于@Html.ShowReadOnlyField(x => x.MyField, "My Field")),而不是那3行。但是,这也假定你想要实现此效果的每个地方都具有相同的div结构。 编辑:请记住只读字段的安全问题,因为它们并不是真正的只读。如果这些数据将在控制器中用于任何事情,最好从数据库重新检索这些数据,因为尽管在HTML表单上是只读的,但用户仍然可以通过操作POST/GET数据来将该值设置为任何他们想要的值。

您能否通过使用辅助程序 @Html.AntiForgeryToken() 来解决安全问题? - Brandon
1
我有所怀疑。我对AntiForgeryToken功能不是很了解,但最有可能的情况是用户可以查看页面源代码以查看他们需要提供什么令牌才能使其工作。伪造令牌更多用于跨站点脚本攻击,而不是用于价值保护,它无法知道某个字段是否应该被提供。任何需要安全的内容都需要在服务器端处理,不能依赖客户端功能来实现安全。 - KallDrexx
我最终只是在控制器中重新加载了我的对象实例。 - Brandon

0
请尝试在页面中序列化模型,然后进行发布?这应该可以解决问题。
<%= Html.Serialize("User",Model) %>

[HttpPost]   
public ActionResult Register([DeserializeAttribute] User user, FormCollection userForm)
{

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接