CurlyPaul
CurlyPaul

Reputation: 1148

Problems back button and resubmitting the form

I am having problems when the back button is used and a form is resubmitted, the value on the model that is bound to the drop down list is not retained on the second submission.

In real life, this code is a report generator - the form collects parameters from the user and then posts it to a results view where the data is displayed. Obviously this is a fairly complex bit of code to post, but below I have some simple code exhibiting the same bug:

I have a model like so:

public class HomeModel
{
    public string SomeText { get; set; }

    public long SelectedItemId { get; set; }

    public IEnumerable<SelectListItem> AvailableItems { get; set; }

}

A form that submits an instance of the model like so:

@using(Html.BeginForm("Result", "Home", FormMethod.Get))
{
    @Html.EditorFor(model => model.SomeText)
    <br />
    @Html.DropDownListFor(model => model.SelectedItemId, Model.AvailableItems)
    <input type="submit" value="submit" />
}

And a view that shows the details, like so

You Typed: @Html.DisplayFor(model => model.SomeText) <br />

You Selected: @Html.DisplayFor(model => model.SelectedItemId)

And a controller to manage it all:

  public class HomeController : Controller
  {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            HomeModel model = new HomeModel();

            List<SelectListItem> items = new List<SelectListItem>();

            for (int i = 0; i < 10; i++)
                items.Add(new SelectListItem() { Value = i.ToString(), Text = i.ToString() });

            model.AvailableItems = items;


            return View(model);
        }

        public ActionResult Result(HomeModel model)
        {
            return View(model);
        }

    }

I fill in the form, press submit. I am redirected to the Results view and all is well.

Then I press back in the browser, and I am shown the Index view again.

Then I submit the form again and things turn sour. The model is not being repopulated with the selected value from my list, despite the list appearing to show the previously selected value in the browser.

The string property is being updated correctly, and this is true in the real world code that I have displaying this behaviour.

This only happens in IE, I am using version 9.

Upvotes: 3

Views: 979

Answers (2)

CurlyPaul
CurlyPaul

Reputation: 1148

Right, this is definitely all working correctly now.

It was related to where I was inserting the script tags for the validation. I was being lazy and just stuck them in at the top of the views, so when the entire page was assembled and rendered they were in the body.

IE seemed to take exception to this and when the back button was pressed, the script references disappeared, as did all of the validation attributes and the 'Id' off the name of my property. Kind of odd but there you go

So, the moral of the story is to always put the scripts in the correct place.

Upvotes: 1

CurlyPaul
CurlyPaul

Reputation: 1148

Well I found the solution.

Short answer: don't suffix your model properties with 'Id'

When I first load the index view in the example, this is what gets rendered:

<SELECT id=SelectedItemId name=SelectedItemId data-val-required="The field is required"...>

When I submit, press back and then check the source, this is what I get:

<select name="SelectedItem" id="SelectedItem">

Notice that the name of the element has been changed, severely disrupting MVC's deserializers.

This can be seen in the URLs that are being posted, when I first post the form, this is the url that is shown in the browser:

http://localhost:57175/Home/Result?SomeText=999&SelectedItemId=1

Then, when I press back and post again, this is what is shown:

http://localhost:57175/Home/Result?SomeText=999&SelectedItem=1

I can live with changing the property name, but the trouble is that it also strips all of the validation attributes that are needed for using unobtrusive validation. Can anyone enlighten me on how to retain those?

Upvotes: 1

Related Questions