從ASP.NET MVC 5開始,Html.DropDownListFor已經提供了對Enum的支持,但在這以前,需要通過幫助方法或擴展方法來讓Html.DropDownListFor顯示枚舉值。
本篇解決在ASP.NET MVC 4 下Html.DropDownListFor顯示默認項的問題。
以上,使用Select是通過Html.DropDownListFor來實現的,Select的選項值是從枚舉中讀出。可以看到,某個枚舉值成了默認選項,而我想讓"==請選擇=="成為Select的默認選項。
在找到解決方法之前,先讓問題重現。
有這樣的一個枚舉。
public enum Status{[EnumDisplayName("啟用")]Enabled = 0,[EnumDisplayName("禁用")]Disabled = 1}
有這樣的一個View Model的Status屬性用來存放枚舉的某個值。
public class MyChoice{public short Status { get; set; }}
這里需要幫助方法,能讀取枚舉的自定義特性EnumDisplayName和枚舉值。
首先是自定義特性。
public class EnumDisplayNameAttribute : Attribute{private string _displayName;public EnumDisplayNameAttribute(string displayName){_displayName = displayName;}public string DisplayName{get{return _displayName;}}}
然后,幫助方法使用反射把元數據讀取出來,最終得到一個SelectListItem的集合。
/// <summary>/// 把枚舉轉換成SelectListItem/// </summary>public class EnumExt{/// <summary>/// 獲取枚舉成員的自定義Attribute的一個屬性值/// </summary>/// <param name="e">枚舉成員</param>/// <returns></returns>public static string GetEnumDescription(object e){//獲取枚舉成員的Type對象Type t = e.GetType();//獲取Type對象的所有字段FieldInfo[] ms = t.GetFields();//遍歷所有字段foreach (FieldInfo f in ms){if (f.Name != e.ToString()){continue;}if (f.IsDefined(typeof(EnumDisplayNameAttribute), true)){return (f.GetCustomAttributes(typeof(EnumDisplayNameAttribute), true)[0] as EnumDisplayNameAttribute).DisplayName;}}return e.ToString();}public static List<SelectListItem> GetSelectList(Type enumType){List<SelectListItem> selectList = new List<SelectListItem>();//selectList.Add(new SelectListItem { Text = "--請選擇--", Value = "",Selected = true});foreach (object e in Enum.GetValues(enumType)){selectList.Add(new SelectListItem { Text = GetEnumDescription(e), Value = ((int)e).ToString() });}return selectList;}}
在控制器中,通過ViewData把SelectListItem的集合實例傳遞到前台。
public ActionResult Index(){ViewData["s"] = EnumExt.GetSelectList(typeof(Status));return View(new MyChoice());}
在視圖頁中:
@Html.DropDownListFor(m => m.Status,(IEnumerable<SelectListItem>)ViewData["s"],"==請選擇==")
現在,就出現了本篇剛開始提到的問題:Select的默認選項是某個枚舉值,而不是"==請選擇=="。
因為枚舉的默認值是0,所以在顯示Select的時候,總是把枚舉值為0枚舉項顯示了出來。
既然枚舉的默認值是無法改變的,那就讓枚舉值為0的枚舉項的自定義特性顯示"==請選擇=="。
public enum Status{[EnumDisplayName("==請選擇==")]None = 0,[EnumDisplayName("啟用")]Enabled = 1,[EnumDisplayName("禁用")]Disabled = 2}
再修改視圖頁中的部分,Html.DropDownListFor不需要提示文字。
@Html.DropDownListFor(m => m.Status,(IEnumerable<SelectListItem>)ViewData["s"])
最后,得到了想要的效果。