[asp.net mvc 奇淫巧技] 03 - 枚举特性扩展解决枚举命名问题和支持HtmlHelper
2017-05-31 08:45
441 查看
一、需求
我们在开发中经常会遇到一些枚举,而且这些枚举类型可能会在表单中的下拉中,或者单选按钮中会用到等。using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Web.Mvc; using System.Web.Routing; namespace Emrys.EnumTools { /// <summary> /// 枚举帮助类 /// </summary> public static class EnumTools { /// <summary> /// 获取当前枚举值的描述 /// </summary> /// <param name="value"></param> /// <returns></returns> public static string GetDescription(this Enum value) { int order; return GetDescription(value, out order); } /// <summary> /// 获取当前枚举值的描述和排序 /// </summary> /// <param name="value"></param> /// <param name="order"></param> /// <returns></returns> public static string GetDescription(this Enum value, out int order) { string description = string.Empty; Type type = value.GetType(); // 获取枚举 FieldInfo fieldInfo = type.GetField(value.ToString()); // 获取枚举自定义的特性DescriptionAttribute object[] attrs = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); DescriptionAttribute attr = (DescriptionAttribute)attrs.FirstOrDefault(a => a is DescriptionAttribute); order = 0; description = fieldInfo.Name; if (attr != null) { order = attr.Order; description = attr.Name; } return description; } /// <summary> /// 获取当前枚举的所有描述 /// </summary> /// <param name="value"></param> /// <returns></returns> public static List<KeyValuePair<int, string>> GetAll<T>() { return GetAll(typeof(T)); } /// <summary> /// 获取所有的枚举描述和值 /// </summary> /// <param name="type"></param> /// <returns></returns> public static List<KeyValuePair<int, string>> GetAll(Type type) { List<EnumToolsModel> list = new List<EnumToolsModel>(); // 循环枚举获取所有的Fields foreach (var field in type.GetFields()) { // 如果是枚举类型 if (field.FieldType.IsEnum) { object tmp = field.GetValue(null); Enum enumValue = (Enum)tmp; int intValue = Convert.ToInt32(enumValue); int order; string showName = enumValue.GetDescription(out order); // 获取描述和排序 list.Add(new EnumToolsModel { Key = intValue, Name = showName, Order = order }); } } // 排序并转成KeyValue返回 return list.OrderBy(i => i.Order).Select(i => new KeyValuePair<int, string>(i.Key, i.Name)).ToList(); } /// <summary> /// 枚举下拉 /// </summary> /// <typeparam name="T">枚举类型</typeparam> /// <param name="html"></param> /// <param name="htmlAttributes"></param> /// <returns></returns> public static MvcHtmlString EnumToolsSelect<T>(this HtmlHelper html, object htmlAttributes = null) { return html.EnumToolsSelect(typeof(T), int.MaxValue, htmlAttributes); } /// <summary> /// 枚举下拉 /// </summary> /// <typeparam name="T">枚举类型</typeparam> /// <param name="html"></param> /// <param name="selectedValue">选择项</param> /// <param name="htmlAttributes"></param> /// <returns></returns> public static MvcHtmlString EnumToolsSelect<T>(this HtmlHelper html, int selectedValue, object htmlAttributes = null) { return html.EnumToolsSelect(typeof(T), selectedValue, htmlAttributes); } /// <summary> /// 枚举下拉 /// </summary> /// <typeparam name="T">枚举类型</typeparam> /// <param name="html"></param> /// <param name="selectedValue">选择项</param> /// <param name="htmlAttributes"></param> /// <returns></returns> public static MvcHtmlString EnumToolsSelect<T>(this HtmlHelper html, T selectedValue, object htmlAttributes = null) { return html.EnumToolsSelect(typeof(T), Convert.ToInt32(selectedValue), htmlAttributes); } /// <summary> /// 枚举下拉 /// </summary> /// <param name="html"></param> /// <param name="enumType">枚举类型</param> /// <param name="selectedValue">选择项</param> /// <param name="htmlAttributes"></param> /// <returns></returns> public static MvcHtmlString EnumToolsSelect(this HtmlHelper html, Type enumType, int selectedValue, object htmlAttributes = null) { // 创建标签 TagBuilder tag = new TagBuilder("select"); // 添加自定义标签 if (htmlAttributes != null) { RouteValueDictionary htmlAttr = htmlAttributes as RouteValueDictionary ?? HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); tag.MergeAttributes(htmlAttr); } // 创建option集合 StringBuilder options = new StringBuilder(); foreach (var item in GetAll(enumType)) { // 创建option TagBuilder option = new TagBuilder("option"); // 添加值 option.MergeAttribute("value", item.Key.ToString()); // 设置选择项 if (item.Key == selectedValue) { option.MergeAttribute("selected", "selected"); } // 设置option option.SetInnerText(item.Value); options.Append(option.ToString()); } tag.InnerHtml = options.ToString(); // 返回MVCHtmlString return MvcHtmlString.Create(tag.ToString()); } /// <summary> /// 下拉枚举 /// </summary> /// <typeparam name="TModel">Model</typeparam> /// <typeparam name="TProperty">属性</typeparam> /// <param name="htmlHelper"></param> /// <param name="expression"></param> /// <param name="htmlAttributes"></param> /// <returns></returns> public static MvcHtmlString EnumToolsSelectFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null) { // 获取元数据meta ModelMetadata modelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); Type enumType = modelMetadata.ModelType; // 设置id name的属性值 var rvd = new RouteValueDictionary { { "id", modelMetadata.PropertyName }, { "name", modelMetadata.PropertyName } }; // 添加自定义属性 if (htmlAttributes != null) { RouteValueDictionary htmlAttr = htmlAttributes as RouteValueDictionary ?? HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); foreach (var item in htmlAttr) { rvd.Add(item.Key, item.Value); } } // 获取验证信息 IDictionary<string, object> validationAttributes = htmlHelper.GetUnobtrusiveValidationAttributes(modelMetadata.PropertyName, modelMetadata); // 添加至自定义属性 if (validationAttributes != null) { foreach (var item in validationAttributes) { rvd.Add(item.Key, item.Value); } } return htmlHelper.EnumToolsSelect(enumType, Convert.ToInt32(modelMetadata.Model), rvd); } } /// <summary> /// 枚举特性 /// </summary> [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)] public class DescriptionAttribute : Attribute { /// <summary> /// 排序 /// </summary> public int Order { get; set; } /// <summary> /// 名称 /// </summary> public string Name { get; set; } /// <summary> /// 显示自定义描述名称 /// </summary> /// <param name="name">名称</param> public DescriptionAttribute(string name) { Name = name; } /// <summary> /// 显示自定义名称 /// </summary> /// <param name="name">名称</param> /// <param name="order">排序</param> public DescriptionAttribute(string name, int order) { Name = name; Order = order; } } /// <summary> /// 枚举Model /// </summary> partial class EnumToolsModel { public int Order { get; set; } public string Name { get; set; } public int Key { get; set; } } }
View Code
最后望对各位有所帮助,本文原创,欢迎拍砖和推荐。
Github:https://github.com/Emrys5/Asp.MVC-03-Enum-rename-htmlhelper
系列课程
[asp.net mvc 奇淫巧技] 01 - 封装上下文 - 在View中获取自定义的上下文[asp.net mvc 奇淫巧技] 02 - 巧用Razor引擎在Action内生成Html代码
[asp.net mvc 奇淫巧技] 03 - 枚举特性扩展解决枚举命名问题和支持HtmlHelper
[asp.net mvc 奇淫巧技] 04 - 你真的会用Action的模型绑定吗?
[asp.net mvc 奇淫巧技] 05 - 扩展ScriptBundle,支持混淆加密javascript
相关文章推荐
- [asp.net mvc 奇淫巧技] 03 - 枚举特性扩展解决枚举命名问题和支持HtmlHelper
- [ASP.net MVC] 将HTML转成PDF档案,使用iTextSharp套件的XMLWorkerHelper (附上解决显示中文问题)
- Asp.net MVC Preview 4 中自定义Jquery的HtmlHelper扩展
- ASP.NET MVC HtmlHelper扩展之Calendar日期时间选择
- Asp.net MVC Preview 4 中自定义Jquery的HtmlHelper扩展
- ASP.NET MVC HtmlHelper 类的扩展方法
- 转:ASP.NET MVC扩展之HtmlHelper辅助方法
- 新版asp.net mvc 分页控件:HtmlHelper扩展
- ASP.NET MVC 3 RC2 版本的一些新特性及AllowHtml属性Bug解决办法
- ASP.NET MVC 3 扩展之给 HtmlHelper 扩展一个 RadioButtonList
- asp.net mvc htmlhelper 扩展方法
- [转]ASP.NET MVC HtmlHelper扩展之Calendar日期时间选择
- dhl: 在 ASP.NET MVC 中创建自定义 HtmlHelper 使用扩展方法创建 HTML Helper
- ASP.NET Core解决MVC视图中的中文被html编码的问题
- ASP.NET MVC HtmlHelper 自定义扩展分页功能
- ASP.Net MVC开发基础学习笔记(2):HtmlHelper与扩展方法
- Asp.Net MVC对类HtmlHelper的自定义扩展方法以及如何调用
- asp.net mvc Htmlhelper简单扩展
- ASP.NET MVC HtmlHelper如何扩展
- asp.net mvc htmlhelper扩展