Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC Model not updating

The Model:

class Address
{
    public string City { get; set; }
    public string Zip { get; set; }
}

The Controller:

[HttpPost]
public ActionResult GetAddress(Address model)
{
    if (!String.IsNullOrEmpty(model.Zip))
    {
        model.City = GetCityByZip(model.Zip);
    }
    return View(model);
}

The View:

<div class="formrow">
    @Html.LabelFor(model => model.City)
    @Html.TextBoxFor(model => model.City) 
    @Html.ValidationMessageFor(model => model.City)
</div>
<div class="formrow">
    @Html.LabelFor(model => model.Zip)
    @Html.TextBoxFor(model => model.Zip) 
    @Html.ValidationMessageFor(model => model.Zip)
</div>

The problem is whenever the city is being modified, it never gets reflected on the view. During debugging, the model.City contains the correct value but it doesn't show up on view. Even something as simple as @Html.TextBoxFor(model => model.City) doesn't display the correct model.City value.

like image 574
xar Avatar asked Aug 07 '12 01:08

xar


People also ask

What is update model in MVC?

In my last article I fetched the data from view to controller using model and save this data into database. I am using the same example in this article. We can also use UpdateModel method to fetch data from view to controller. UpdateModel is the method which is generics type and takes parameter of model type.

What is ModelState Clear () in MVC?

Clear() is required to display back your model object. If you are getting your Model from a form and you want to manipulate the data that came from the client form and write it back to a view, you need to call ModelState. Clear() to clean the ModelState values.

Can we use update panel in MVC?

With MVC you are rendering your Html stream much more directly than the abstracted/pseudo-stateful box that WebForms wraps you up in. Of course UpdatePanel can be used in much more complex scenarios than this (it can contain INPUTS, supports ViewState and triggers across different panels and other controls).


2 Answers

HtmlHelpers get the model values from the model state and not the model when you update and return the model. In order to update and return the model, add this line of code in your post method:

ModelState.Clear();

or you could set the value of city in the ModelState itself:

ModelState["City"].Value = GetCityByZip(model.Zip);
like image 103
Tommy Avatar answered Oct 02 '22 07:10

Tommy


As Tommy noted, this is, somewhat counterintuitively, the correct behavior since form data submitted on post gets first priority when binding the data to the returned view. This makes some sense as the user is likely to have made a validation error when re-returning the same view and gets to resume their form entry as is without the problems of losing form input when restoring a page

One other option is to manually insert the value for the input

So instead of this:

@Html.TextBoxFor(model => model.City)

Do this instead:

<input type="text" name="City" value="@Model.City" />

* which will grab the value directly off the model

Or even better:

<input type="text" value="@Model.City"
       name="@Html.NameFor(model => model.City)"
       id="@Html.IdFor(model => model.City)" />

*Note: this won't bring in data-val attributes. If you're using them on this property for client side validation, you'll need to build list of data validation attributes for a given element

Additional Resources

  • HiddenFor not getting correct value from view model
  • HTML.HiddenFor is not updating on a postback
  • ASP.NET MVC Postbacks and HtmlHelper Controls ignoring Model Changes
like image 32
KyleMit Avatar answered Oct 02 '22 09:10

KyleMit