How does asp.net MVC remember my incorrect values โ€‹โ€‹during postback?

It works, but how ???

I have a controller action for the message:

[AcceptVerbs(HttpVerbs.Post )] public ActionResult Edit(Person person) { bool isvalid = ModelState.IsValid; etc. 

The Person object has the BirthDate property, enter DateTime. When I enter some invalid data on the form, say 'blabla' that the Datetime is obviously invalid, it fills all (other) Person properties with the correct data and the BirthDate property with a new empty DateTime. The bool isvalid value is false. So far so good.

Then I do this:

 return View(p); 

and in the view, I have this:

 <%= Html.TextBox("BirthDate", String.Format("{0:g}", Model.BirthDate)) %> <%= Html.ValidationMessage("BirthDate", "*") %> 

Ant here it is: I am EXPECTING a model to contain a new empty DateTime, because I did not enter any new data. Secondly, when the view shows something, it must be a DateTime, because Model.BirthDate cannot contain anything other than DateTime. But, to my surprise, it shows a text field with the value "blabla"! (and red * after him)

Which of the good results, because the user can see what he typed incorrectly, but how to transfer this line (blabla) to the "View" field in the DateTime field?

EDIT: The ModelState info helped me a lot. I also notice that in MVC 2, when you create your own template for Html.EditorFor () you must implement this behavior yourself. I created

 DateTime.ascx 

in the / views / shared / EditorTemplates folder, and there I had to check if the model had a mistake for this property value, and if so, show invalid data instead of model data.

So, in the view, I use this:

  <%= Html.LabelFor(model => model.DateOfBirth) %> 

and in DateTime.ascx I use this:

 <% bool invalidData = false; string propertyName = ViewData.ModelMetadata.PropertyName; ModelState ms = ViewData.ModelState[propertyName]; if (ms != null) { invalidData = ms.Errors.Count > 0; } string valueToshow = invalidData ? ViewData.ModelState[propertyName].Value.AttemptedValue : String.Format("{0:g}", Model); %> <input class="text-box single-line" id="<%= propertyName %>" name="<%= propertyName %>" type="text" value="<%= valueToshow %>" /> 
+6
asp.net-mvc asp.net-mvc-2
source share
3 answers

ModelState contains a KeyValuePairs for each form element, with the key being the name of the field and the value being what you put in the field. Then the Html helpers look at the ModelState, and if you do not explicitly specify a value, they will pull the value out of the ModelState.

+10
source share

The previously entered value is stored in ModelState. When you have an error in the form, the helper extracts the value from the ModelState instead of using the values โ€‹โ€‹from the Model or those that were specially supplied (under the hood, if you do not give an explicit value, it will be the default value for the model, if it is, when there are errors not).

+4
source share

I had a code in "postback" that would delete invalid promo codes and smooth out the response. Even if you update the model with a new value, it will not be displayed, because the value of ModelState takes precedence (as others have already answered).

  <%= Html.TextBox("PromoCode", Model.PromoCodes) %> 

But if you have a case where this happens and you do not want the old value to be preserved, you need to do this:

 ModelState.Remove("PromoCode"); 

or explicitly set a new value in modelstate (perhaps the best approach):

 ModelState.SetModelValue("PromoCode", new ValueProviderResult(newValue, newValue, CultureInfo.CurrentCulture)); 
+1
source share

All Articles