hiddenFor helper is pulling id from action parameter, not the viewModel

ぃ、小莉子 提交于 2019-12-06 02:30:35

How come HiddenFor is getting it's wires crossed and pulling the value of 117?

That's by design. All HTML helpers such as TextBoxFor and HiddenFor first use the value of ModelState when binding and then the value of the model. I presume your controller action looks like this:

public ActionResult Foo(int id)
{
    SomeModel model = ...
    // At this stage model.Id = 0
    return View(model);
}

The thing is that the default model binder adds a value into the ModelState with the key id which is used by the helper and the model property value is ignored. This is not a bug. It is how the HTML helpers are designed. It's a bit confusing in the beginning when you don't know it, but once you get accustomed to this behavior you don't fall in the trap a second time.

One possibility to fix the problem is to remove this value from ModelState:

public ActionResult Foo(int id)
{
    ModelState.Remove("id");
    SomeModel model = ...
    // At this stage model.Id = 0
    return View(model);
}

Or rename the Id property inside your model to something else to avoid the conflict.

As an alternative to changing your field names, you can make a new helper method that doesn't use the route values when evaluating what to put in the value attribute.

I created this helper for the extremely common id case:

public static MvcHtmlString HiddenIdFor<TModel, TValue>(this HtmlHelper<TModel> html,
        Expression<Func<TModel, TValue>> expression)
    {
        var value = ModelMetadata.FromLambdaExpression(expression, html.ViewData).Model.ToString();
        var builder = new TagBuilder("input");
        builder.MergeAttribute("type", "hidden");
        builder.MergeAttribute("name", ExpressionHelper.GetExpressionText(expression));
        builder.MergeAttribute("value", value);
        return MvcHtmlString.Create(builder.ToString(TagRenderMode.SelfClosing));

}

Then you can use this in the template:

@Html.HiddenIdFor(m => m.Id) 
@Html.HiddenIdFor(m => m.ProjectId)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!