问题
I'm working on an application that has the option of using a VIN decoder to get car information. You can type in the VIN, or you can select through dropdowns, manufacturer, year, make, model, etc.
The manufacturer dropdown is the only thing initialized on the page, with no selected value. Selecting a manufacturer will find all available years for that manufacturer and return the list of years, as well as returning the list of manufacturers and the one that was selected. Selecting a year will then return list of available manufacturers, years and makes, with the selected manufacturer and selected year both identified, and so on down through the application.
This workflow works fine and all of my dropdowns display correctly. When entering a VIN though, I have selected values for each, and still find the lists of available options, and render the page exactly as I would if someone had selected options by hand up to that point. All of the dropdowns render correctly with the proper selected attributes when I do this except the manufacturer.
I have tried to isolate it as much as possible, and have stripped out everything else, and I have this now:
View:
@model My_Project.Models.Data
@using System.Web.Helpers
@using (Html.BeginForm("Temp", "Home", FormMethod.Post, new { id = "formIndex" }))
{
<div>
VIN:
@Html.TextBox("vin", Model.VIN) <button type="submit">Go!</button>
</div>
<div>
Manufacturer: (@Model.ManufacturerId)
@Html.DropDownListFor(m => m.ManufacturerId, Model.Manufacturers, new { style = "width: 175px;" })
</div>
}
Model:
namespace My_Project.Models
{
[Serializable]
public class Data
{
public string VIN { get; set; }
public int ManufacturerId { get; set; }
public SelectList Manufacturers { get; set; }
}
}
Controller:
public ActionResult Temp()
{
Data model = new Data
{
Manufacturers = DBAccess.getManufacturers()
};
Session["ModelData"] = model;
return View(model);
}
[HttpPost]
public ActionResult Temp(Data newData)
{
Data oldData = Session["ModelData"] as Data;
oldData.ManufacturerId = 20;
Session["ModelData"] = oldData;
return View(oldData);
}
If I set the ManufacturerId in Temp(), then my dropdown list renders correctly with whatever manufacturer selected. If it is set in the post response though, the dropdown list renders with all the correct options, but without the correct manufacturer selected. And if you look in the view, I actually have it displaying the manufacturerId to me to make sure it is getting the data correctly, and manufacturerId is set to a value that is in the list, but it is not selected.
I can't figure out what the difference is between these two instances given that the model used in rendering the view looks identical. On top of that, if the post method is called by selecting the manufacturer (I have that functionality stripped out at this point), it would return the same model but also render correctly.
What would be causing this to not render correctly on the return from the post?
回答1:
If you need to set a value from controller post method
, I think you need to update the ModelState
with the new value. I think it is because even if you pass updated model to the view, ModelState is still holding the old value.
Try this:
[HttpPost]
public ActionResult Temp(Data newData)
{
Data oldData = Session["ModelData"] as Data;
oldData.ManufacturerId = 20;
Session["ModelData"] = oldData;
//Update model state with new ManufacturerId here
CultureInfo myCulture = new System.Globalization.CultureInfo("en-GB");
ModelState.SetModelValue("ManufacturerId",
new ValueProviderResult((object)oldData.ManufacturerId,
oldData.ManufacturerId.ToString(), myCulture));
return View(oldData);
}
来源:https://stackoverflow.com/questions/19982876/dropdownlistfor-not-always-showing-selected-value