Why is my textBoxFor using my route data?

2019-05-01 12:00发布

问题:

So I have these three lines:

<div style="background-color: lightgreen;">@Html.TextBoxFor(m => m.Id)</div>
<div style="background-color: green;">@Html.DisplayTextFor(m => m.Id)</div>
<div style="background-color: pink;">@Model.Id</div>

I've identified that the lightgreen value is not my Model.Id but the Id that is set by my route:

routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "MyFunController", action = "Index", id = UrlParameter.Optional });

I've come accross some explanations here:

  • http://forums.asp.net/t/1792086.aspx/1
  • http://www.hanselman.com/blog/TheWeeklySourceCode38ASPNETMVCBetaObscurityModelStateIsValidIsFalseBecauseModelBinderPullsValuesFromRouteData.aspx
  • http://ayende.com/blog/3683/reproducing-a-bug

But they have all left me on my appetite. I'm looking for a smart way to work around this, I don't want to change my model's property names nor do I want to change the name of the route item. If I do it will represent a lot of work for me and is not ideal.

I'm sure I'm not the only one with this issue?

(This is MVC 4)

Thanks!

回答1:

You could remove the problematic value from the ModelState (which is where the Html helpers are taking it from) in the controller action that is rendering the view:

public ActionResult SomeAction(int id)
{
    ModelState.Remove("Id");
    MyViewModel model = ...
    return View(model);
}

Now it's the Id property of your view model that's gonna get used by the TextBox and not the one coming from the route.

Obviously that's only an ugly horrible workaround. The correct way is to of course properly define your view models so that you do not have such naming collisions.