4

I'm completely stumped.
I'm doing a searchform in MVC2 (I've done dozen others on this project, all working fine.)
Global.asax has this route:

  routes.MapRoute("OnlineHelpSearchIndex",
                          "Help/Search/{expression}/{page}",
                          new { controller = "OnlineHelp", action = "Search", expression = UrlParameter.Optional, page=1 });

The expression is a base64 encoded string. I decode it in controller, pass it to a model which has a property named Expression, and display it in a PartialView in a TextBox. (Then when the user clicks a link or presses enter, I encode the string in javascript and send it to "/Help/Search/"+value)

I have several searchboxes built this way (each with a route SomeModule/Search/{expression}), and one of them is not working.

<%:Html.DisplayFor(m => m.Expression)%>
<%: Model.Expression %>
<%:Html.TextAreaFor(m => m.Expression)%>
<%:Html.TextBoxFor(m => m.Expression)%>
<%:Html.EditorFor(m => m.Expression)%>

The first two display the correct expression, the other three displays the expression in the url.
I tried hardcoding a string into the model, the first two displayed the hardcoded string, the other three displayed whatever was in the url. How is it possible?
(I even tried with JS disabled, so it is a server side issue)

TDaver
  • 7,164
  • 5
  • 47
  • 94

2 Answers2

3

I know this is an old thread, but I figured I would answer it anyway. The reason this is happening is intentional, it is due to ModelState. See this question for another case: Asp.net MVC ModelState.Clear

Long story short, you're POSTing form data to a controller and returning a View, and using Helpers. Therefore, MVC assumes this is a failure on validation and is returning the ModelState value, not the value of your Model data. The first two are displaying correctly because they are not editors, the other 3 are editors, so they're showing ModelState.

Either call ModelState.Clear() in the controller to blow it away, or implement another design pattern, such as POST, Redirect, GET.

Mike P.
  • 1,920
  • 1
  • 18
  • 20
  • 1
    Only 1 upvote is not enough for this answer. I had a sleepless night to solve this issue! Thank you, Mike. – prinkpan Dec 10 '19 at 05:57
1

Try to change the name of the expression parameter in both the routes.MapRoute and in your OnlineHelp/Search controller/action method:

routes.MapRoute("OnlineHelpSearchIndex",
                          "Help/Search/{exprs}/{page}",
                          new { controller = "OnlineHelp", action = "Search", exprs = UrlParameter.Optional, page=1 });

(or, if you prefer, you can change the name of the Expression property of your model).

This often happens working with form fields created by HtmlHelper methods such as TextBoxFor/EditorFor, when the ViewModel has one or more properties that share the same name of a Router/Controller parameter: you can easily check this looking at the generated HTML code, your input-type fields created by the HtmlHelper methods will most likely have an id='Expression' attribute which causes the whole problem.

Darkseal
  • 9,205
  • 8
  • 78
  • 111
  • You said that *one of them* is not working, right? The case you mentioned is working as expected: `Html.DisplayFor` and `Model.Expression` don't produce an input-type field so they aren't affected/overwritten, the other three cases do. – Darkseal Feb 26 '12 at 11:24
  • No, I mean `<%:Html.TextBoxFor(m => m.Expression)%>` works in all but two places. – TDaver Feb 26 '12 at 13:29
  • I would need too look at the rest of the code: all I can say is, given your example, I get the same results for the above reasons. To better understand your specific issue, I suggest to set a breakpoint inside your controller's method and watch inside the `ModelState`: you should see the action parameters who most likely affecting your `TextBoxFor`(s). You can also remove them all (`Modelstate.Clear()`) or selectively (the various `keys`) before returning the model to the view, but you generally don't want to do that if you need to perform validation checks in the same Request. – Darkseal Feb 26 '12 at 22:34
  • 2
    Truth to be told, I got fed up with this issue more than a week ago, and written `` – TDaver Feb 26 '12 at 22:38