Question

I have the problem documented here and here and here and especially here where, in an ASP.NET MVC4 view, the html helper function @Html.HiddenFor(m => m.ID) will use the "wrong" data and cause data corruption.

This is a massive problem, and the accepted "solution" is to simply be aware of this and design around it. I think that is a poor solution. (Incidentally, we use something like this instead: <input type="hidden" value="@Model.ID" />)

Every few months, I or a colleague forget and use that html helper, and all hell breaks loose before we track down the problem... once again.

How can I eliminate the use of this function, to avoid mistakes in the future?
- it's not our code, so we cannot mark it with [Obsolete]
- we can override the HtmlHelper, but that's a lot of work just to eliminate one function
- can I write a unit test to pick out this code from the view? (and fail test if that call is detected)
- other ideas?

Was it helpful?

Solution

This is not a "problem", it's the way it's supposed to work. And it's not just HiddenFor that does it, every helper will do it. it's the way MVC is designed to work. The fact that you don't seem to understand how MVC works is the real problem.

This is part of the ModelState subsystem, and you are wise to know exactly how this works. Yes, it's not always intuitive, but it's far better that you actually know how things work than to pretend they don't exist, because you'll end up bitten in other ways with other helpers.

But, if you choose otherwise, I would suggest configuring StyleCop to deal with this issue

OTHER TIPS

If you want some static analysis tool, you my look on CodeContracts available also via Visual Studio Gallery + there are other tools (payed, as much as I'm aware of).

The main idea is: you define via attributes conditions in the code and that conditions are validate before binary generation, or at runtime by calling associated method. But considering fact that you're not allowed or can not change the code that uses that function, may be

Roslyn would be more suitable for you. So you can investigate your AST and find out if there are some calls on that non desirable function.

Note: depends on architecture it can become fairly complex issue, but, by the way these are options that you can consider imo.

I am not sure if this will help, but what I have done to remove HiddenFors in my code is to implement a kind of ViewState. The model is serialized to the client and my model binder is set to deserialize this. I put up the code at https://github.com/willseitz/ModelViewState. This might help you come up with a general solution.

Erik is right, it is supposed to work like that when doing HTTP POST. Here is a good explanation: Blog link. The blog suggests several solutions including yours Bobby B :-)

Quote from the blog: "ASP.NET MVC assumes that if you’re rendering a View in response to an HTTP POST, and you’re using the Html Helpers, then you are most likely to be redisplaying a form that has failed validation. Therefore, the Html Helpers actually check in ModelState for the value to display in a field before they look in the Model. This enables them to redisplay erroneous data that was entered by the user, and a matching error message if needed. ... Html Helpers (i.e. Html.Hidden and Html.TextBox) check ModelState first… and so display the values that were received by the action, not those we modified."

Thanks to nemesv and Rhys Stephens (stackoverflow link)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top