Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hiddenfor not getting correct value from view model

Tags:

asp.net-mvc

I have a multi-step file import process. I have a hidden form input in my view that I am trying to populate with the "CurrentStep" from the view model.

<% = Html.HiddenFor(model => model.CurrentStep) %>

CurrentStep is an Enum and I always get the default value rather than the one I provided to the view model. on the other hand this gets me the correct value:

<p><% = Model.CurrentStep %></p>

I realise I could just hand code the hidden input but I want to know: what am I doing wrong? Is there a better way to keep track of the current step between POSTs?

like image 928
user427875 Avatar asked Jan 29 '11 15:01

user427875


People also ask

What is the use of HiddenFor in MVC?

HiddenFor() The Html. HiddenFor<TModel, TProperty> extension method is a strongly typed extension method generates a hidden input element for the model property specified using a lambda expression. Visit docs.microsoft.com to know all the overloads of HiddenFor() method.

How do you pass view model to view?

The recommended way to pass the ViewModel to the View is to make use of the View method. The View method takes the model as one of the argument, which internally sets it to the ViewData. Model Property.

How does HTML HiddenFor work?

HiddenFor<TModel,TProperty>(HtmlHelper<TModel>, Expression<Func<TModel,TProperty>>, IDictionary<String,Object>) Returns an HTML hidden input element for each property in the object that is represented by the specified expression, using the specified HTML attributes.


3 Answers

What you are doing wrong is that you are trying to modify the value of a POSTed variable in your controller action. So I suppose you are trying to do this:

[HttpPost] public ActionResult Foo(SomeModel model) {     model.CurrentStep = Steps.SomeNewValue;     return View(model); } 

and html helpers such as HiddenFor will always first use the POSTed value and after that the value in the model.

So you have a couple of possibilities:

  1. Remove the value from the modelstate:

    [HttpPost] public ActionResult Foo(SomeModel model) {     ModelState.Remove("CurrentStep");                 model.CurrentStep = Steps.SomeNewValue;     return View(model); } 
  2. Manually generate the hidden field

    <input type="hidden" name="NextStep" value="<%= Model.CurrentStep %>" /> 
  3. Write a custom helper which will use the value of your model and not the one that's being POSTed

like image 74
Darin Dimitrov Avatar answered Sep 23 '22 19:09

Darin Dimitrov


My solution was to use Darin's second option, because option 1 (clearing from the model state) means hard coding a string (and the naming convention can be tricky with complex models), and wanted to avoid option 3 because I already have so many custom helpers.

<input type="hidden" name="@Html.NameFor(x => Model.SomeId)" value="@Model.SomeId" />

Just a reminder that you can use Html.NameFor to keep things clean.

like image 32
Zac Avatar answered Sep 23 '22 19:09

Zac


Make sure you model property has a "set" operator.

This won't get updated on post-back:

@Html.HiddenFor( m => m.NoSeq)

public Class MyModel
{
    int _NoSeq;
    public NoSeq
    {
        get { return _NoSeq };
    }
}
like image 20
gharel Avatar answered Sep 24 '22 19:09

gharel