ASP.NET?MVC下拉框中顯示枚舉項(xiàng)
本篇將通過3種方式,把枚舉項(xiàng)上的自定義屬性填充到下拉框:
1、通過控制器返回List<SelectListItem>類型給前臺(tái)視圖
2、通過為枚舉類型屬性打上UIHint屬性讓模版顯示枚舉項(xiàng)
3、通過自定義元數(shù)據(jù)提供器DataAnnotationsModelMetadataProvider讓模版顯示枚舉項(xiàng)
我們經(jīng)常會(huì)把類型為Int16的屬性通過枚舉來獲得。比如:
public class SomeClass
{
public int16 Status{get;set;}
}對(duì)應(yīng)的枚舉:
public enum StatusEnum
{
Enable = 0,
Disable = 1
}在MVC視圖中可能會(huì)這樣寫:
<select id="sel"> <option value="">==選擇狀態(tài)==</option> <option value="0">啟用</option> <option value="1">禁用</option> </select>
如果枚舉的項(xiàng)發(fā)生變化怎么辦?比如:
public enum StatusEnum
{
Enable = 0,
Disable = 1,
NeverComeback = 2
}如果修改每一頁的代碼,顯然是不合理的。最理想的做法是:為每一個(gè)枚舉項(xiàng)打上屬性,顯示的時(shí)候直接讀取枚舉以及枚舉項(xiàng)屬性值。
通過控制器返回List<SelectListItem>類型給前臺(tái)視圖
定義一個(gè)Model,其中有一個(gè)類型為Int16的屬性Status,這個(gè)屬性用來接收枚舉值。
using System;
using System.ComponentModel.DataAnnotations;
namespace MvcApplication1.Models
{
public class Stadium
{
public int Id { get; set; }
[Display(Name = "場(chǎng)館名稱")]
public string Name { get; set; }
[Display(Name = "是否啟用")]
public Int16 Status { get; set; }
}
}為每個(gè)枚舉項(xiàng)打上的屬性需要我們自定義,通過構(gòu)造函數(shù)接收名稱,并提供一個(gè)屬性供外部訪問。
using System;
namespace MvcApplication1.Extension
{
public class EnumDisplayNameAttribute : Attribute
{
private string _displayName;
public EnumDisplayNameAttribute(string displayName)
{
this._displayName = displayName;
}
public string DisplayName
{
get { return _displayName; }
}
}
}為每個(gè)枚舉項(xiàng)打上自定義屬性。
using MvcApplication1.Extension;
namespace MvcApplication1.Models.Enum
{
public enum StatusEnum
{
[EnumDisplayName("啟用")]
Enable = 0,
[EnumDisplayName("禁用")]
Disable = 1
}
}我們的目的是在控制器獲取List<SelectListItem>集合,然后傳遞到前臺(tái)視圖?,F(xiàn)在,枚舉和枚舉項(xiàng)上的自定義屬性都有了,有必要?jiǎng)?chuàng)建一個(gè)幫助類來幫我們獲取List<SelectListItem>集合。
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Web.Mvc;
namespace MvcApplication1.Extension
{
public class EnumExt
{
/// <summary>
/// 根據(jù)枚舉成員獲取自定義屬性EnumDisplayNameAttribute的屬性DisplayName
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
public static string GetEnumCustomDescription(object e)
{
//獲取枚舉的Type類型對(duì)象
Type t = e.GetType();
//獲取枚舉的所有字段
FieldInfo[] ms = t.GetFields();
//遍歷所有枚舉的所有字段
foreach (FieldInfo f in ms)
{
if (f.Name != e.ToString())
{
continue;
}
//第二個(gè)參數(shù)true表示查找EnumDisplayNameAttribute的繼承鏈
if (f.IsDefined(typeof (EnumDisplayNameAttribute), true))
{
return
(f.GetCustomAttributes(typeof(EnumDisplayNameAttribute), true)[0] as EnumDisplayNameAttribute)
.DisplayName;
}
}
//如果沒有找到自定義屬性,直接返回屬性項(xiàng)的名稱
return e.ToString();
}
/// <summary>
/// 根據(jù)枚舉,把枚舉自定義特性EnumDisplayNameAttribut的Display屬性值撞到SelectListItem中
/// </summary>
/// <param name="enumType">枚舉</param>
/// <returns></returns>
public static List<SelectListItem> GetSelectList(Type enumType)
{
List<SelectListItem> selectList = new List<SelectListItem>();
foreach (object e in Enum.GetValues(enumType))
{
selectList.Add(new SelectListItem(){Text = GetEnumCustomDescription(e),Value = ((int)e).ToString()});
}
return selectList;
}
}
}在控制器中,通過ViewData把List<SelectListItem>集合往前臺(tái)傳??刂破靼?個(gè)方法,一個(gè)方法用來顯示創(chuàng)建視圖界面,另一個(gè)用來顯示編輯視圖界面。
//創(chuàng)建
public ActionResult Index()
{
ViewData["s"] = EnumExt.GetSelectList(typeof (StatusEnum));
return View(new Stadium());
}
//編輯
public ActionResult Edit()
{
Stadium s = new Stadium()
{
Id = 2,
Name = "水立方",
Status = (short)StatusEnum.Disable
};
ViewData["s"] = EnumExt.GetSelectList(typeof(StatusEnum));
return View(s);
}在強(qiáng)類型的創(chuàng)建視圖界面中,通過@Html.DropDownListFor(model => model.Status,(List<SelectListItem>)ViewData["s"])接收來自控制器的數(shù)據(jù)。
@model MvcApplication1.Models.Stadium
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Stadium</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Status)
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.Status,(List<SelectListItem>)ViewData["s"])
@Html.ValidationMessageFor(model => model.Status)
</div>
<p>
<input type="submit" value="添加" />
</p>
</fieldset>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}在強(qiáng)類型的編輯視圖界面中,同樣通過@Html.DropDownListFor(model => model.Status,(List<SelectListItem>)ViewData["s"])接收來自控制器的數(shù)據(jù)。
@model MvcApplication1.Models.Stadium
@{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Edit</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Stadium</legend>
@Html.HiddenFor(model => model.Id)
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Status)
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.Status,(List<SelectListItem>)ViewData["s"])
@Html.ValidationMessageFor(model => model.Status)
</div>
<p>
<input type="submit" value="編輯" />
</p>
</fieldset>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}創(chuàng)建界面:

編輯界面:

通過為枚舉類型屬性打上UIHint屬性讓模版顯示枚舉項(xiàng)
由于模版是根據(jù)屬性類型來判斷的,再定義一個(gè)Model,其中一個(gè)屬性類型是枚舉。
using System.ComponentModel.DataAnnotations;
using MvcApplication1.Models.Enum;
namespace MvcApplication1.Models
{
public class Stadium1
{
public int Id { get; set; }
[Display(Name = "場(chǎng)館名稱")]
public string Name { get; set; }
[Display(Name = "是否啟用")]
public StatusEnum Status { get; set; }
}
}在Views/Shared/EditorTemplates文件夾下創(chuàng)建Enum.cshtml,用來處理類型為Enum的屬性。
@using System.ComponentModel.DataAnnotations
@using System.Reflection
@using MvcApplication1.Extension
@{
var selectList = new List<SelectListItem>();
string optionLabel = null;
object htmlAttributes = null;
var enumType = (Type)Model.GetType();
foreach (var value in Enum.GetValues(enumType))
{
var field = enumType.GetField(value.ToString());
var option = new SelectListItem() {Value = value.ToString()};
var display = field.GetCustomAttributes(typeof (EnumDisplayNameAttribute), false).FirstOrDefault() as EnumDisplayNameAttribute;
if (display != null)
{
option.Text = display.DisplayName;
}
else
{
option.Text = value.ToString();
}
option.Selected = object.Equals(value, Model);
selectList.Add(option);
}
}
@Html.DropDownList("",selectList, optionLabel, htmlAttributes)控制器中有2個(gè)方法用來顯示創(chuàng)建和編輯視圖界面。
//創(chuàng)建
public ActionResult TemplateCreate()
{
return View(new Stadium1());
}
//編輯
public ActionResult TemplateEdit()
{
Stadium1 s = new Stadium1()
{
Id = 2,
Name = "水立方",
Status = StatusEnum.Disable
};
return View(s);
}強(qiáng)類型的創(chuàng)建視圖界面:
@model MvcApplication1.Models.Stadium1
@{
ViewBag.Title = "TemplateCreate";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>TemplateCreate</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Stadium</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Status)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Status)
@Html.ValidationMessageFor(model => model.Status)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}強(qiáng)類型的編輯視圖界面:
@model MvcApplication1.Models.Stadium1
@{
ViewBag.Title = "TemplateEdit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>TemplateEdit</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Stadium</legend>
@Html.HiddenFor(model => model.Id)
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Status)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Status)
@Html.ValidationMessageFor(model => model.Status)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}最后,給Stadium1的枚舉屬性,打上UIHint屬性,指明使用公共Enum類型模版Views/Shared/EditorTemplates/Enum.cshtml。
using System.ComponentModel.DataAnnotations;
using MvcApplication1.Models.Enum;
namespace MvcApplication1.Models
{
public class Stadium1
{
public int Id { get; set; }
[Display(Name = "場(chǎng)館名稱")]
public string Name { get; set; }
[Display(Name = "是否啟用")]
[UIHint("Enum")]
public StatusEnum Status { get; set; }
}
}創(chuàng)建視圖界面:

編輯視圖界面:

通過自定義元數(shù)據(jù)提供器DataAnnotationsModelMetadataProvider讓模版顯示枚舉項(xiàng)
如果覺得為屬性打上[UIHint("Enum")]屬性麻煩的話,還可以通過數(shù)據(jù)提供器,為所有類型為Enum的屬性指明模版。

當(dāng)然自定義的元數(shù)據(jù)提供器是需要在全局中注冊(cè)的。
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
//注冊(cè)自定義元數(shù)據(jù)提供其
ModelMetadataProviders.Current = new CustomMetadataProvider();
}
}現(xiàn)在可以把Stadium的[UIHint("Enum")]注釋掉。
總結(jié)
如果,我們想在下拉框中顯示枚舉項(xiàng),首先給枚舉項(xiàng)打上自定義屬性,通過反射可以拿到自定義屬性的相關(guān)屬性值。
如果,想在控制器方法中獲取List<SelectListItem>集合往前臺(tái)傳,我們可以封裝一個(gè)方法,根據(jù)枚舉返回List<SelectListItem>集合;
如果想根據(jù)屬性的類型顯示枚舉模版,要么給枚舉屬性打上[UIHint("Enum")],要么在全局自定義一個(gè)DataAnnotationsModelMetadataProvider。
到此這篇關(guān)于ASP.NET MVC下拉框中顯示枚舉項(xiàng)的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- ASP.NET?MVC實(shí)現(xiàn)多選下拉框
- 詳解ASP.NET MVC 下拉框的傳值的兩種方式
- ASP .NET 可編輯輸入自動(dòng)匹配的下拉框
- 詳解ASP.NET MVC之下拉框綁定四種方式
- ASP.NET MVC下拉框聯(lián)動(dòng)實(shí)例解析
- ASP.NET中DropDownList下拉框列表控件綁定數(shù)據(jù)的4種方法
- ASP.NET實(shí)現(xiàn)級(jí)聯(lián)下拉框效果實(shí)例講解
- ASP.NET多彩下拉框開發(fā)實(shí)例
- asp.net mvc下拉框Html.DropDownList 和DropDownListFor的常用方法
- asp.net中js+jquery添加下拉框值和后臺(tái)獲取示例
- asp.net 實(shí)現(xiàn)下拉框只讀功能
相關(guān)文章
linq to sql 中,如何解決多條件查詢問題,答案,用表達(dá)式樹! (下)
在上一篇中,我們做了基于linq to sql 的多條件組合查詢,但通過監(jiān)視數(shù)據(jù)庫發(fā)現(xiàn),這樣做的成本比較高,每次都要取出全部的數(shù)據(jù)到內(nèi)存進(jìn)行篩選.2011-08-08
導(dǎo)致Asp.Net站點(diǎn)重啟10個(gè)原因小結(jié)分析
Asp.Net站點(diǎn)有時(shí)候會(huì)莫名其妙的重啟,什么原因?qū)е碌膮s不得而知,經(jīng)過一番折騰后,我總結(jié)了導(dǎo)致Asp.Net站點(diǎn)重啟的10個(gè)原因,需要的朋友可以參考下。2011-08-08
asp.net 關(guān)于==?:和if()else()條件判斷等效例子
關(guān)于==?:和if()else() 等效例子2010-03-03
asp.net關(guān)于Cookie跨域(域名)的問題
Cookie是一個(gè)偉大的發(fā)明,它允許Web開發(fā)者保留他們的用戶的登錄狀態(tài)。但是當(dāng)你的站點(diǎn)有一個(gè)以上的域名時(shí)就會(huì)出現(xiàn)問題了。在Cookie規(guī)范上說,一個(gè)cookie只能用于一個(gè)域名,不能夠發(fā)給其它的域名。因此,如果在瀏覽器中對(duì)一個(gè)域名設(shè)置了一個(gè)cookie,這個(gè)cookie對(duì)于其它的域名將無效。如果你想讓你的用戶從你的站點(diǎn)中的其中一個(gè)進(jìn)行登錄,同時(shí)也可以在其它域名上進(jìn)行登錄,這可真是一個(gè)大難題。2012-12-12
DataGridView展開與收縮功能實(shí)現(xiàn)
我們今天將要講到DataGridView之行的展開與收縮,包括功能是如何實(shí)現(xiàn)的,感興趣的小伙伴們可以參考一下2015-09-09
asp.net使用DataTable構(gòu)造Json字符串的方法
這篇文章主要介紹了asp.net使用DataTable構(gòu)造Json字符串的方法,涉及asp.net字符串序列化、遍歷及構(gòu)造等操作技巧,需要的朋友可以參考下2015-12-12

