3

我有一个具有多个字段的模型的视图。当我在 GET 上呈现视图时,我有一个隐藏字段存储一个此时为空的代码。然后我发布并在操作中通过模型向此代码字段添加一个值并将模型发送到视图,例如:

return View (model);

当视图呈现时,隐藏字段没有代码值,但视图包含在第一步中输入的所有其他值。所以现在当我在第二个按钮上发布时,传递给操作的模型不包含我在第一个发布响应中传递给它的隐藏代码值。

如果我在第一篇文章中更新了模型并使用新值将其发送回视图,我是否应该将该代码存储在可用视图中的隐藏输入中并能够再次将其发布回操作?

我刚刚还意识到,如果我在第一个回帖中更改任何模型字段并将更新的模型发送到视图,它只会保留第一个 POST 操作的值。我这里有缓存问题吗?,我该如何管理这种行为?谢谢

4

2 回答 2

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 值,该值是一个空字符串,而不是您在操作中修改的值。

于 2012-06-24T20:58:01.523 回答
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());
}
于 2014-06-04T18:44:24.757 回答