0

我有一个视图来创建一个用户,如下所示。

<% 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是嫌疑人。所以在action中返回视图之前添加一行如下。

[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);
}

果然,这行得通。隐藏字段现在具有正确用户 ID 的值。

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

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

4

1 回答 1

4

操作成功后你应该使用

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

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

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

编辑:

如果您不想绑定整个对象,则应该使用[Bind (Exclude)]或者您应该自己定义SaveUserSaveUser(string userName, string password)构建UserViewModel对象。这将使您免于由模型绑定器和模型值生成的错误,您不知道这些错误来自何处。

于 2009-10-13T14:42:02.163 回答