This is a follow on from the following question:
MVC 3 + $.ajax - response seems to be caching output from partial view
There is a detailed description of th
This was unexpected behavior for me, and although I understand the reason why it's necessary to give ModelState precedence, I needed a way to remove that entry so that the value from Model is used instead.
Here are a couple methods I came up with to assist with this. The RemoveStateFor method will take a ModelStateDictionary, a Model, and an expression for the desired property, and remove it.
HiddenForModel can be used in your View to create a hidden input field using only the value from the Model, by first removing its ModelState entry. (This could easily be expanded for the other helper extension methods).
///
/// Returns a hidden input field for the specified property. The corresponding value will first be removed from
/// the ModelState to ensure that the current Model value is shown.
///
public static MvcHtmlString HiddenForModel(this HtmlHelper helper,
Expression> expression)
{
RemoveStateFor(helper.ViewData.ModelState, helper.ViewData.Model, expression);
return helper.HiddenFor(expression);
}
///
/// Removes the ModelState entry corresponding to the specified property on the model. Call this when changing
/// Model values on the server after a postback, to prevent ModelState entries from taking precedence.
///
public static void RemoveStateFor(this ModelStateDictionary modelState, TModel model,
Expression> expression)
{
var key = ExpressionHelper.GetExpressionText(expression);
modelState.Remove(key);
}
Call from a controller like this:
ModelState.RemoveStateFor(model, m => m.MySubProperty.MySubValue);
or from a view like this:
@Html.HiddenForModel(m => m.MySubProperty.MySubValue)
It uses System.Web.Mvc.ExpressionHelper to get the name of the ModelState property. This is especially useful when you have "Nested" models since the key name isn't obvious.