我有一个包含多个字段的模型的视图。当我在GET上渲染视图时,我有一个隐藏字段,存储一个此时为空的代码。然后我发布POST并在操作中通过模型向此代码字段添加值并将模型发送到视图,如:
return View (model);
当视图呈现时,隐藏字段没有代码值,但视图确实包含在第一步中输入的所有其他值。所以现在当我发布第二个按钮时,传递给动作的模型不包含我在第一个帖子响应时传递给它的隐藏代码值。
如果我在第一篇文章中更新了模型并将其发送回带有新值的视图,那么我是否应该将该代码存储在视图中的隐藏输入中并且能够将其重新发布回操作?
我还意识到,如果我更改第一篇文章中的任何模型字段并将更新的模型发送到视图,它将仅保留第一个POST操作的值。我这里有缓存问题吗?我该如何管理这种行为?感谢
答案 0 :(得分:5)
您应该在更改POST操作中的值之前将其从ModelState中删除:
[HttpPost]
public ActionResult Foo(MyViewModel model)
{
// update the value of the model that was POSTed to some new value
model.SomeProperty = "some new value";
// remove POSTed value from the modelstate if you intend to modify it here
ModelState.Remove("SomeProperty");
return View(model);
}
您需要执行此操作的原因是因为Html.HtextBoxFor
,Html.HiddenFor
等Html帮助程序首先在绑定时使用来自modelstate的值,然后使用模型中的值。如果不从ModelState中删除该值,则HiddenFor
帮助程序将使用原始POSTed值,该值为空字符串,而不是您在操作中修改的值。
答案 1 :(得分:0)
问题与达林指出的相同。这是另一种解决方案:
public static MvcHtmlString MyHiddenFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes = null) {
var value = expression.Compile().Invoke(html.ViewData.Model);
TagBuilder input = new TagBuilder("input");
input.Attributes["type"] = "hidden";
input.Attributes["id"] = html.IdFor(expression).ToString();
input.Attributes["name"] = html.NameFor(expression).ToString();
if (htmlAttributes != null)
input.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
input.Attributes["value"] = value == null ? "" : value.ToString();
return new MvcHtmlString(input.ToString());
}