简体   繁体   中英

Why does SelectList SelectedValue work on HttpGet but not on HttpPost?

Using MVC3 I have found that setting a SelectList's selected value correctly renders the view on an HttpGet, but fails to render correctly on HttpPost. I have inspected the Model before they are forwarded to the View on HttpPost and they are correctly being updated, it just seems the View is not rendering the selected tag correctly.

On HttpPost, the <select> is rendered exactly as it existed after any edits but before submission of the form. The m.SelectedWidgetId = 2; in the HttpPost method is executed, updates the model, but is not reflected in the View.

What am I missing here?

Model:

public class WidgetModel
{
    private Widget[] Widgets {
        get
        {
            return new Widget[] { 
                new Widget { Id=1, Name="Item 1" },
                new Widget { Id=2, Name="Item 2" },
                new Widget { Id=3, Name="Item 3" }
            };
        }
    }
    public SelectList WidgetList
    {
        get
        {
            return new SelectList(Widgets.ToList(), "Id", "Name", SelectedWidgetId);
        }
    }
    public int SelectedWidgetId { get; set; }
}

View:

@model thisProject.Models.WidgetModel

@using (Html.BeginForm())
{
    @Html.DropDownListFor(m => m.SelectedWidgetId, Model.WidgetList, "Select...");      
    <input type='submit' />                                                                                    
}

Controller Methods;

public ActionResult Widget()
{
    var m = new WidgetModel();
    m.SelectedWidgetId = 1;
    return View(m);
}
[HttpPost]
public ActionResult Widget(WidgetModel m)
{
    m.SelectedWidgetId = 2;
    return View(m);
}

That happens because HTML helpers always use the values in the request before the ones in the model when rendering a value. This basically means that if you want to modify some value in the POST action you need to remove it from the model state first:

[HttpPost]
public ActionResult Widget(WidgetModel m)
{
    ModelState.Remove("SelectedWidgetId");
    m.SelectedWidgetId = 2;
    return View(m);
}

or the helper will simply ignore the value you are manually setting and use the one that was POSTed by the user.

in asp.net mvc the selectedvalue of selectList is overridden by value of the property for which dropdown is created when we use strongly typed helper ie

<%:Html.DropDownListFor(x=>x.SelectedWidgetID, ---,----)%>

in this case value of Model.selectedwidgetID will override the value that is set in

new SelectList(Widgets.ToList(), "Id", "Name", SelectedWidgetId);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM