我对 ASP.NET MVC 3 还是比较陌生的,我有一个概念性的问题要问那些在这里有更多经验的人。
让我们说(简单的)例子,我有一个事件的注册表单。该表单将显示事件的名称,以及一个文本框,用户可以在其中输入其名称。 ViewModel 看起来像这样:
public class SignupFormViewModel {
public string EventName { get; set; }
[Required]
public string VolunteerName { get; set; }
}
Razor View 可能如下所示:
<h2>Sign up for @Model.EventName</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<div class="editor-field">
@Html.EditorFor( model => model.VolunteerName )
@Html.ValidationMessageFor( model => model.VolunteerName )
</div>
}
如果用户将表单提交回服务器并且 ModelState 无效,我们将返回原始 View 并传回模型,以便我们可以显示错误。 (我们假设此示例是客户端未处理的错误)
问题是在我上面显示的示例 View 中,EventName 没有与表单数据一起提交。我只想将它用于页面内容,而不是表单字段。但是如果我必须返回并向用户显示验证错误,我就丢失了 EventName 属性。
那么,通过返回相同 View 的帖子保留这个非表单字段项目有哪些选择?
我知道我可以创建一个隐藏字段来保存 EventName 属性,但是强制将每个非表单字段属性放入隐藏字段的做法有些不对劲。我也知道我可以进入 Controller 中的 HttpPost 操作,并在返回 View 之前将该数据重新加载回模型,但这也感觉很笨拙。
我想我对执行此操作的基本方法有很好的了解,但我想知道是否有更好的方法或最佳实践让您感觉更干净……或者我是否只需要学习处理它:-)
谢谢
最佳答案
为此使用隐藏字段没有任何问题。当您实际上不希望它们显示为表单字段时,这是通过请求持久化事物的一种非常传统的方式。
请记住,HTTP 是无状态的,因此在页面上放置某些内容并在 POST 请求中再次获取它实际上是一种在多个请求中持久保存该数据的方法,而不是使用另一种产生有状态错觉的机制。
如果您觉得这会使您的标记过于困惑,您可以尝试将这些值放入 TempData
中。初始 GET 请求上的集合,它仅在下一个请求期间存在,允许您在下一个 Controller 操作中获取它:
TempData["MyVar"] = model.EventName
但是,如果您希望将其保留在您的模型中,就像传统的(并且 - 在我看来 - 最好的)这样做的方式,隐藏字段仍然是要走的路:
@Html.HiddenFor(m => m.EventName)
如需进一步阅读,您也可以考虑 cookies或 session state ,尽管这些都不会在模型中保留值。然而,这两种机制都有其局限性,我在 another answer, here. 中对此进行了概述。
关于asp.net-mvc - 在 ASP.NET MVC 中持久化非表单模型数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16924500/