2009-10-13 117 views
0

我有一个视图来创建一个用户,如下所示。查看数据字典在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); 
} 

果然,这工作。隐藏字段现在具有正确用户标识的值。

我们找到了治疗症状的方法,但是问题的根源在哪里?

我不喜欢在每次返回另一个视图之前清理视图数据字典的想法。

回答

4

操作成功之后,你应该使用

return RedirectToAction("EditUser", new { id = user.Id }); 

或类似代码。当前的ModelState用于生成视图和模型绑定器未绑定Id。

[Bind(Exclude = "Id")]也可以工作,但重定向会创建新的页面(不使用当前的ModelState)并且是更好的解决方案。

编辑:

如果你不想绑定整个对象,你应该使用[Bind (Exclude)]或你应该定义为SaveUserSaveUser(string userName, string password)建立自己的UserViewModel对象。这可以帮助您避免模型联编程序和Model值生成的错误,您不知道从哪里来。

+0

++,这是处理这种情况的首选方法。它还解决了用户刷新页面和无意中重新发布相同表单帖子的问题。根据系统的不同,如果你的行为不是幂等的,那可能是一件坏事。 – 2009-10-13 14:47:26

+0

@LukLed,@Joel:谢谢你们的帮助。 我的UserViewModel比我在这里发布的更复杂,因此我编写了自定义模型绑定器。我的一个朋友找到了一种方法来使用默认的联编程序,而不使用自定义联编程序,所以我会努力切换到它。 – 2009-10-13 17:02:11

+0

@LukLed:使用RedirectToAction后,问题仍然存在,我不得不使用ViewData = new ViewDataDictionary();换句话说,使用重定向并不能解决问题。有什么我失踪? – 2009-10-14 01:17:57