Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC Hidden field via HTML Helper in Form Post issue

I have an issue when using a hidden field in an MVC Form Post. When the hidden field is generated via a HTML Helper it won't preserve it's value during the postback. But when using a HTML tag, it works.

Unfortunately this one has taken me a whole day to work out this work around.

Here is what I'm doing... (excuse any spelling, re-typed code for SO):

View Model

public class SomeViewModel
{
    public int MyProperty1 { get; set; }
    public int MyProperty2 { get; set; }
    public int MyProperty3 { get; set; }
}

Post method

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult MyActionMethod(SomeViewModel someViewModel, string command)
{
  ...
  ...
  // someViewModel.MyProperty1
  ...
  ...
}

View

@using (Html.BeginForm("MyActionMethod", "SomeController", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()

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

    <div class="col-md-2">
        <input type="hidden" [email protected] name="MyProperty1" />
        <input type="submit" name="command" value="Button1" class="btn btn-primary" />
        <input type="submit" name="command" value="Button2" class="btn btn-success" />
    </div>
    <div class="col-md-1"></div>
    <div class="col-md-1">
        <input type="submit" name="command" value="Button3" class="btn btn-danger" />
    </div>
    <div class="col-md-8"></div>
}

In the above View code, the HTML helper hidden field (@Html.HiddenFor(m => m.MyProperty1)) does NOT work. But the HTML tag hidden field (input type="hidden" [email protected] name="MyProperty1") DOES work. I only have one or the other enabled. Both shown here are for display purposes.

I'd prefer to use the HTML Helper syntax, but can live with the HTML tag.

Things to note:

  1. The View is using multiple submit buttons.

  2. The View is using a partial view. Currently no content in the partial view and nothing is being done with it.

I can't see how these would affect the issue. Thought I'd mention it, in case.

Question: Can anyone explain why the HTML Helper isn't working?


***** UPDATE *****

Thanks to Stephen Muecke for pointing out what needed to be included in my question. Moreover an extra thank you for guessing what I was actually doing but I couldn't articulate it.

I'm updating the View Model property in the ActionMethod(), and when the same View is re-rendered, the View Model property doesn't reflect the new value. Rather it is keeping it's initial value, and not preserving the new value.

like image 561
OpcodePete Avatar asked Feb 09 '23 21:02

OpcodePete


1 Answers

Although not obvious and I found it difficult to find many articles on this subject to clarify it for me in the past the default behaviour in ASP.NET MVC is the following:

If you are using HTML Helpers and you are rendering the same View in response to a POST it is assumed that you are responding to failed form validation. Therefore the values before being set in the POST will always be rendered back in the view from ModelState.

You have a few options:

  1. ModelState.Clear(); in your post. Not recommended as the framework has not been designed this way.
  2. Use the Post-Redirect-Get pattern and only display validation failure, as the framework was designed (as @StephenMuecke mentions).
  3. If you are not bothered about validation do not use HtmlHelpers
  4. Use Request.Form values instead and remove the SomeViewModel someViewModel parameter. Wouldn't recommend this as you lose all benefits of model binding.
  5. Use ModelState.Remove for the specific field, again not recommended.

The best article I found on this was article from Simon Ince in 2010:

ASP.NET MVC’s Html Helpers Render the Wrong Value!

Another one by Rick Strahl:

ASP.NET MVC Postbacks and HtmlHelper Controls ignoring Model Changes

like image 133
hutchonoid Avatar answered Feb 12 '23 10:02

hutchonoid