View data dictionary overriding model data in ASP.NET MVC

让人想犯罪 __ 提交于 2019-12-23 04:24:11

问题


I have a view to create a user as follows.

<% 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>
<}%>

When the "Create" button is clicked, the HTML form is posted to an action called "SaveUser" that accepts the "POST" verb only as follows.

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

After the user is saved, the page is redirected to the "EditUser" view with

<p>
    <label for="Id">Id:</label>
    <%= Html.Hidden("Id", Model.Id)%>
</p>

Here is the problem: the value for the hidden field kept showing up as zero though. Model.Id is greater than zero. It seemed that something else is overriding the model view value. ViewDataDictonary was a suspect. So a line is added before returning the view in the action as follows.

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

Sure enough, this worked. The hidden field now has a value of the correct user ID.

We found a way to treat the symptom, but where is the source of the problem?

I don't like the idea of clearing view data dictionary every time before a returning another view.


回答1:


After successful operation you should use

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

or similar code. The current ModelState is used to generate view and model binder didn't bind Id.

[Bind(Exclude = "Id")] could also work, but the redirection creates new page (not using current ModelState) and is a better solution.

Edit:

If you don't want to bind whole object, you should use [Bind (Exclude)] or you should just define SaveUser as SaveUser(string userName, string password) and build the UserViewModel object yourself. This will save you from errors generated by model binder and Model values, that you don't know where come from.



来源:https://stackoverflow.com/questions/1560579/view-data-dictionary-overriding-model-data-in-asp-net-mvc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!