I must be missing something about how this works, because I can’t figure this out. Maybe someone here can help.
My Address object has a property called ValidationStatus. It is not visible on the screen, but has a hidden field:
@Html.HiddenFor(model => model.ValidationStatus)
So, I run the program, open an existing address, which has a ValidationStatus of “OK”, and change the address so that it is invalid. I then posts the form to the Controller. The object’s Validate method calls the 3rd-party service, which returns an error. The code sets ValidationStatus to “Invalid” and return the View with a validation message.
When the View loads, ValidationStatus is properly set to “Invalid” as I can see by debugging the following statement in the View:
@if (Model.ValidationStatus == "Invalid") //show an additional field.
So I enters data in the new field and again post the form to the Controller. In the first line in the controller, I put a breakpoint and check collection[“ValidationStatus”] in the immediate window. It is “OK” instead of “Invalid”.
What am I missing here? Why didn’t the value stick? There is nothing on the client side that can change that value.
Here’s the controller code (pretty basic, really):
[HttpPost]
public ActionResult Index(FormCollection collection, string destinationControllerName)
{
PrepareSecondaryData(); // loads drop-down lists in case the View needs to be returned
try
{
if (!TryUpdateModel(_policy))
return View(_policy);
if (!_services.PolicyEditor.SavePolicy(_policy))
return View(_policy);
}
catch (Exception exp)
{
UIHelper.Log(UIHelper.LogLevel.Error, this, "Error during Save", exp);
ViewBag.Error = UIHelper.GenericErrorMessage();
return View(_policy);
}
return RedirectToAction("Index", destinationControllerName);
}
When rendering view to client, ModelState has the highest priority in providing values of model. That is the case in your situation. When the view is first time sent to client,
ValidationStatuscorrespondingModelState["ValidationStatus"]has not got value, so it takes model’s value – “OK”. When it is posted to server,ModelState["ValidationStatus"]is populated with “OK” – sent from hidden field from client. And when validated by 3rd party and returned back again, even thoughmodel.ValidationStatus == "Invalid", theModelState["ValidationStatus"] == "OK", so according to higher priority of latter, ModelState sets value “OK” for the model. And the client gets value “OK” in the hidden field. To fix it, do something likeGeneral idea is that corresponding record in ModelState array should have correct value for the model.
UPDATE:
Or alternatively, clear value from modelstate, to make MVC use value from model.
ModelState.Remove("ValidationStatus")