博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MVC中下拉框显示枚举项
阅读量:6167 次
发布时间:2019-06-21

本文共 8327 字,大约阅读时间需要 27 分钟。

原文:

本篇将通过3种方式,把枚举项上的自定义属性填充到下拉框:

1、通过控制器返回List<SelectListItem>类型给前台视图
2、通过为枚举类型属性打上UIHint属性让模版显示枚举项
3、通过自定义元数据提供器DataAnnotationsModelMetadataProvider让模版显示枚举项

 

我们经常会把类型为Int16的属性通过枚举来获得。比如:

public class SomeClass{    public int16 Status{get;set;}}

对应的枚举:

public enum StatusEnum
{
Enable = 0,
Disable = 1
}

在MVC视图中可能会这样写:

 

如果枚举的项发生变化怎么办?比如:

public enum StatusEnum
{
Enable = 0,
Disable = 1,
NeverComeback = 2
}

如果修改每一页的代码,显然是不合理的。最理想的做法是:为每一个枚举项打上属性,显示的时候直接读取枚举以及枚举项属性值。

 

  通过控制器返回List<SelectListItem>类型给前台视图

定义一个Model,其中有一个类型为Int16的属性Status,这个属性用来接收枚举值。

using System;
using System.ComponentModel.DataAnnotations;
 
namespace MvcApplication1.Models
{
public class Stadium
{
public int Id { get; set; }
 
[Display(Name = "场馆名称")]
public string Name { get; set; }
 
[Display(Name = "是否启用")]
public Int16 Status { get; set; }
}
}

为每个枚举项打上的属性需要我们自定义,通过构造函数接收名称,并提供一个属性供外部访问。

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; }
}
}
}

为每个枚举项打上自定义属性。

using MvcApplication1.Extension;
 
namespace MvcApplication1.Models.Enum
{
public enum StatusEnum
{
[EnumDisplayName("启用")]
Enable = 0,
[EnumDisplayName("禁用")]
Disable =  1
}
}

我们的目的是在控制器获取List<SelectListItem>集合,然后传递到前台视图。现在,枚举和枚举项上的自定义属性都有了,有必要创建一个帮助类来帮我们获取List<SelectListItem>集合。

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Web.Mvc;
 
namespace MvcApplication1.Extension
{
public class EnumExt
{
/// 
/// 根据枚举成员获取自定义属性EnumDisplayNameAttribute的属性DisplayName
/// 
/// 
/// 
public static string GetEnumCustomDescription(object e)
{
//获取枚举的Type类型对象
Type t = e.GetType();
 
//获取枚举的所有字段
FieldInfo[] ms = t.GetFields();
 
//遍历所有枚举的所有字段
foreach (FieldInfo f in ms)
{
if (f.Name != e.ToString())
{
continue;
}
 
//第二个参数true表示查找EnumDisplayNameAttribute的继承链
if (f.IsDefined(typeof (EnumDisplayNameAttribute), true))
{
return
(f.GetCustomAttributes(typeof(EnumDisplayNameAttribute), true)[0] as EnumDisplayNameAttribute)
.DisplayName;
}
}
 
//如果没有找到自定义属性,直接返回属性项的名称
return e.ToString();
}
 
/// 
/// 根据枚举,把枚举自定义特性EnumDisplayNameAttribut的Display属性值撞到SelectListItem中
/// 
/// 枚举
/// 
public static List
GetSelectList(Type enumType)
{
List
selectList = new List
();
foreach (object e in Enum.GetValues(enumType))
{
selectList.Add(new SelectListItem(){Text = GetEnumCustomDescription(e),Value = ((int)e).ToString()});
}
return selectList;
}
}
}
 

 

在控制器中,通过ViewData把List<SelectListItem>集合往前台传。控制器包含2个方法,一个方法用来显示创建视图界面,另一个用来显示编辑视图界面。

//创建
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);
}

在强类型的创建视图界面中,通过@Html.DropDownListFor(model => model.Status,(List<SelectListItem>)ViewData["s"])接收来自控制器的数据。

@model MvcApplication1.Models.Stadium
 
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
 

Index

 
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
 
Stadium
 
@Html.LabelFor(model => model.Name)
 
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
 
 
@Html.LabelFor(model => model.Status)
 
@Html.DropDownListFor(model => model.Status,(List
)ViewData["s"])
@Html.ValidationMessageFor(model => model.Status)
 
 

 
}
 
 
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
 

 

在强类型的编辑视图界面中,同样通过@Html.DropDownListFor(model => model.Status,(List<SelectListItem>)ViewData["s"])接收来自控制器的数据。

@model MvcApplication1.Models.Stadium
 
@{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
 

Edit

 
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
 
Stadium
 
@Html.HiddenFor(model => model.Id)
 
@Html.LabelFor(model => model.Name)
 
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
 
 
@Html.LabelFor(model => model.Status)
 
@Html.DropDownListFor(model => model.Status,(List
)ViewData["s"])
@Html.ValidationMessageFor(model => model.Status)
 
 

 
}
 
 
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
 

 

创建界面:

 

编辑界面:

 

  通过为枚举类型属性打上UIHint属性让模版显示枚举项

由于模版是根据属性类型来判断的,再定义一个Model,其中一个属性类型是枚举。

using System.ComponentModel.DataAnnotations;
using MvcApplication1.Models.Enum;
 
namespace MvcApplication1.Models
{
public class Stadium1
{
public int Id { get; set; }
 
[Display(Name = "场馆名称")]
public string Name { get; set; }
 
[Display(Name = "是否启用")]
public StatusEnum Status { get; set; }
}
}

 

在Views/Shared/EditorTemplates文件夹下创建Enum.cshtml,用来处理类型为Enum的属性。

@using System.ComponentModel.DataAnnotations
@using System.Reflection
@using MvcApplication1.Extension
 
@{
var selectList = new List
();
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个方法用来显示创建和编辑视图界面。

//创建
public ActionResult TemplateCreate()
{
return View(new Stadium1());
}
 
//编辑
public ActionResult TemplateEdit()
{
Stadium1 s = new Stadium1()
{
Id = 2,
Name = "水立方",
Status = StatusEnum.Disable
};
return View(s);
}

 

强类型的创建视图界面:

@model MvcApplication1.Models.Stadium1
 
@{
ViewBag.Title = "TemplateCreate";
Layout = "~/Views/Shared/_Layout.cshtml";
}
 

TemplateCreate

 
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
 
Stadium
 
@Html.LabelFor(model => model.Name)
 
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
 
 
@Html.LabelFor(model => model.Status)
 
@Html.EditorFor(model => model.Status)
@Html.ValidationMessageFor(model => model.Status)
 
 

 
}
 
 
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
 

强类型的编辑视图界面:

@model MvcApplication1.Models.Stadium1
 
@{
ViewBag.Title = "TemplateEdit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
 

TemplateEdit

 
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
 
Stadium
 
@Html.HiddenFor(model => model.Id)
 
@Html.LabelFor(model => model.Name)
 
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
 
 
@Html.LabelFor(model => model.Status)
 
@Html.EditorFor(model => model.Status)
@Html.ValidationMessageFor(model => model.Status)
 
 

 
}
 
 
@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 = "场馆名称")]
public string Name { get; set; }
 
[Display(Name = "是否启用")]
[UIHint("Enum")]
public StatusEnum Status { get; set; }
}
}
 

 

创建视图界面:

编辑视图界面:

 

  通过自定义元数据提供器DataAnnotationsModelMetadataProvider让模版显示枚举项

如果觉得为属性打上[UIHint("Enum")]属性麻烦的话,还可以通过数据提供器,为所有类型为Enum的属性指明模版。

 

当然自定义的元数据提供器是需要在全局中注册的。

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);
 
//注册自定义元数据提供其
ModelMetadataProviders.Current = new CustomMetadataProvider();
}
}

现在可以把Stadium的[UIHint("Enum")]注释掉。

 

  总结

如果,我们想在下拉框中显示枚举项,首先给枚举项打上自定义属性,通过反射可以拿到自定义属性的相关属性值。

如果,想在控制器方法中获取List<SelectListItem>集合往前台传,我们可以封装一个方法,根据枚举返回List<SelectListItem>集合;

如果想根据属性的类型显示枚举模版,要么给枚举属性打上[UIHint("Enum")],要么在全局自定义一个DataAnnotationsModelMetadataProvider。

转载地址:http://hrcba.baihongyu.com/

你可能感兴趣的文章
奇怪的打印纸盘故障
查看>>
hyperledger v1.0.5 区块链运维入门(一)
查看>>
Mybatis-mapper-xml-基础
查看>>
5. GC 调优(基础篇) - GC参考手册
查看>>
Windows 7 XP 模式颜色质量只有16位的解决
查看>>
SonicWall如何安全模式升级防火墙
查看>>
Linux IPC实践(3) --具名FIFO
查看>>
从Atlas到Microsoft ASP.NET AJAX(6) - Networking, Application Services
查看>>
成长之路---写好一个类
查看>>
读取 java.nio.ByteBuffer 中的字符串(String) 写入方式flash.utils.ByteArray.writeUTF
查看>>
范围管理和范围蔓延
查看>>
android90 bind方式启动服务service调用service里的方法
查看>>
前端开发薪资之各地区对比(图文分析)(share)
查看>>
对做“互联网产品”的一些想法
查看>>
SPI协议及其工作原理浅析【转】
查看>>
原生js编写的安全色拾色器
查看>>
iOS:VFL语言
查看>>
让时间处理简单化 【第三方扩展类库org.apache.commons.lang.time】
查看>>
用scikit-learn学习DBSCAN聚类
查看>>
Linux设备模型(热插拔、mdev 与 firmware)【转】
查看>>