ASP.Net MVC SelectList not 'Selecting' Correct Item
I have been asked to look at a bug in some ASP.Net MVC code and have a (to me) very odd problem with a SelectList.
The code from the controller to generate the items (a method to return a SelectList, there are 5 in total). Each SelectList is then saved into the ViewData collection.
List<SelectListItem> items = new List<SelectListItem>();
string yesText = "Yes";
string noText = "No";
if (ci.LCID.Equals((int)LanguageCodes.FRANCE))
{
yesText = "Oui";
noText = "Non";
}
SelectLi开发者_如何学编程stItem yesItem = new SelectListItem();
yesItem.Text = yesText;
yesItem.Value = ((int)MarketingBy.Yes).ToString();
yesItem.Selected = selectedValue != null && selectedValue.Equals(int.Parse(yesItem.Value));
SelectListItem noItem = new SelectListItem();
noItem.Text = noText;
noItem.Value = ((int)MarketingBy.No).ToString();
noItem.Selected = selectedValue != null && selectedValue.Equals(int.Parse(noItem.Value));
items.Add(yesItem);
items.Add(noItem);
return new SelectList(items, "Value", "Text", yesItem.Selected ? yesItem.Value : noItem.Value);
A quick 'quickwatch' at the point of creation suggests everything is ok:
At the point the view is being rendered, the values still look ok. However when the view loads, the first item in the list is always selected. The HTML generated is:
<tr>
<td>Fax</td>
<td>
<select id="MarketingByFax" name="MarketingByFax">
<option value="134300002">Yes</option>
<option value="134300001">No</option>
</select>
</td>
</tr>
(Other values ommitted for clarity).
Any ideas? Or avenues to research? The author is adamant that this was working 'up til last week' (I have no idea either way).
Edit: Code for the view -
<td><%: Html.DropDownList("MarketingByFax", (SelectList)ViewData["MarketingByFaxList"])%></td>
This code looks just horrible in every imaginable aspect (IMHO of course). I have no idea why it doesn't work and I don't want to know. All I can do is to suggest you how to improve it (so you can stop reading this post if you are looking for a solution about why your code doesn't work as I have no freaking idea).
So the first improvement would be to get rid of any ViewData
and introduce a view model:
public class MyViewModel
{
public string SelectedValue { get; set; }
public IEnumerable<SelectListItem> Items { get; set; }
}
then I would have a controller action that would populate this view model:
public ActionResult Index()
{
var model = new MyViewModel
{
// I want to preselect the second value
SelectedValue = "No",
Items = new[]
{
new SelectListItem { Value = "Yes", Text = "yeap !" },
new SelectListItem { Value = "No", Text = "nope !" },
}
};
return View(model);
}
and in my strongly typed view I would simply bind the helper to the view model:
<%= Html.DropDownListFor(
x => x.SelectedValue,
new SelectList(Model.Items, "Value", "Text")
) %>
Also if you want to work with some enum types you may find the following extension method useful.
See how easy it is? No more ugly casts with ViewData
, no more need to define any lists and specify some complicated conditions, ...
Remark: once again, those are just my 2¢, you can continue the combat with ViewData
if you will.
you can try
<%: Html.DropDownList("MarketingByFax", (IEnumerable<SelectListItem>)ViewData["MarketingByFaxList"])%>
dropdwon has an overload that accepts the enumeration of Selectlist type objects and it sets the value of list automatically depending upon Selected property of selectListItems in the list. for this you have to set
ViewData["MarketingByFaxList"] = items;//where item is IEnumerable<SelectListItem> or List<SelectListItem> as you used in your code
精彩评论