查看数据字典在ASP.NET MVC中重写模型数据
问题描述:
我有一个视图来创建一个用户,如下所示。查看数据字典在ASP.NET MVC中重写模型数据
<% using (Html.BeginForm("SaveUser", "Security")) {%>
<p>
<label for="UserName">UserName:</label>
<%= Html.TextBox("UserName") %>
<%= Html.ValidationMessage("UserName", "*") %>
</p>
<p>
<label for="Password">Password:</label>
<%= Html.TextBox("Password") %>
<%= Html.ValidationMessage("Password", "*") %>
</p>
<p>
<input type="submit" value="Create" />
</p>
<}%>
当点击“创建”按钮,在HTML表单发送名为“SaveUser”的行动只接受如下的“POST”动词。
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveUser(UserViewModel user)
{
//user.Id is zero before save
//Save the user. Code omitted...
//user.Id is now greater than zero
//redirect to edit user view
return View("EditUser", user);
}
用户保存后,页面会被重定向到“EditUser”视图与
<p>
<label for="Id">Id:</label>
<%= Html.Hidden("Id", Model.Id)%>
</p>
这里的问题是:为隐藏字段的值保持显示为零点虽然。 Model.Id
大于零。看起来其他的东西正在压倒模型视图的价值。 ViewDataDictonary
是一个嫌疑人。因此,在返回操作中的视图之前添加一行,如下所示。
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveUser(UserViewModel user)
{
//user.Id is zero before save
//Save the user. Code omitted...
//user.Id is now greater than zero
//clear the view data
ViewData = new ViewDataDictionary();
//redirect to edit user view
return View("EditUser", user);
}
果然,这工作。隐藏字段现在具有正确用户标识的值。
我们找到了治疗症状的方法,但是问题的根源在哪里?
我不喜欢在每次返回另一个视图之前清理视图数据字典的想法。
答
操作成功之后,你应该使用
return RedirectToAction("EditUser", new { id = user.Id });
或类似代码。当前的ModelState用于生成视图和模型绑定器未绑定Id。
[Bind(Exclude = "Id")]
也可以工作,但重定向会创建新的页面(不使用当前的ModelState)并且是更好的解决方案。
编辑:
如果你不想绑定整个对象,你应该使用[Bind (Exclude)]
或你应该定义为SaveUser
和SaveUser(string userName, string password)
建立自己的UserViewModel
对象。这可以帮助您避免模型联编程序和Model值生成的错误,您不知道从哪里来。
++,这是处理这种情况的首选方法。它还解决了用户刷新页面和无意中重新发布相同表单帖子的问题。根据系统的不同,如果你的行为不是幂等的,那可能是一件坏事。 – 2009-10-13 14:47:26
@LukLed,@Joel:谢谢你们的帮助。 我的UserViewModel比我在这里发布的更复杂,因此我编写了自定义模型绑定器。我的一个朋友找到了一种方法来使用默认的联编程序,而不使用自定义联编程序,所以我会努力切换到它。 – 2009-10-13 17:02:11
@LukLed:使用RedirectToAction后,问题仍然存在,我不得不使用ViewData = new ViewDataDictionary();换句话说,使用重定向并不能解决问题。有什么我失踪? – 2009-10-14 01:17:57