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?
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.
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.
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.
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:
Remove the value from the modelstate:
[HttpPost] public ActionResult Foo(SomeModel model) { ModelState.Remove("CurrentStep"); model.CurrentStep = Steps.SomeNewValue; return View(model); }
Manually generate the hidden field
<input type="hidden" name="NextStep" value="<%= Model.CurrentStep %>" />
Write a custom helper which will use the value of your model and not the one that's being POSTed
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.
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 };
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With