Asp.net
如何為枚舉製作預設編輯器模板?
如何為枚舉創建預設編輯器模板?我的意思是:我可以做這樣的事情:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Enum>" %> <% -- any code to read the enum and write a dropdown -->並將其放在名稱下的 EditorTemplates 文件夾中
Enum.ascx?這是我嘗試過的問題的解決方法,但這不是我需要的。
這是我的枚舉:
public enum GenderEnum { /// <summary> /// Male /// </summary> [Description("Male Person")] Male, /// <summary> /// Female /// </summary> [Description("Female Person")] Female }我製作了一個名為的模板
GenderEnum.acsx並將其放入Shared/EditorTemplates文件夾中。這是模板:<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<AlefTech.HumanResource.Core.GenderEnum>" %> <%@ Import Namespace="AlefTech.HumanResource.WebModule.Classes" %> <%=Html.DropDownListFor(m => m.GetType().Name, Model.GetType()) %>當然方法是我自己的:
public static class HtmlHelperExtension { public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type enumType) { List<SelectListItem> list = new List<SelectListItem>(); Dictionary<string, string> enumItems = enumType.GetDescription(); foreach (KeyValuePair<string, string> pair in enumItems) list.Add(new SelectListItem() { Value = pair.Key, Text = pair.Value }); return htmlHelper.DropDownListFor(expression, list); } /// <summary> /// return the items of enum paired with its descrtioption. /// </summary> /// <param name="enumeration">enumeration type to be processed.</param> /// <returns></returns> public static Dictionary<string, string> GetDescription(this Type enumeration) { if (!enumeration.IsEnum) { throw new ArgumentException("passed type must be of Enum type", "enumerationValue"); } Dictionary<string, string> descriptions = new Dictionary<string, string>(); var members = enumeration.GetMembers().Where(m => m.MemberType == MemberTypes.Field); foreach (MemberInfo member in members) { var attrs = member.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attrs.Count() != 0) descriptions.Add(member.Name, ((DescriptionAttribute)attrs[0]).Description); } return descriptions; } }但是,即使這對我有用,但這不是我要問的。相反,我需要以下工作:
程式碼
Shared\EditorTemplates\Enum.acsx:<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Enum>" %> <%@ Import Namespace="System.Web.Mvc.Html" %> <%@ Import Namespace="WhereMyExtentionMethod" %> <%=Html.DropDownListFor(m => m.GetType().Name, Model.GetType()) %>有了這個,我就不必再為每個枚舉製作模板了。
謝謝大家的貢獻
Yngvebn,我之前嘗試過你的解決方案(在你的最後評論中),但我唯一沒有做的是
<dynamic>,我用<Enum>泛型類型代替。最後的解決方案是:
創建一個名為 Enum.acsx 的模板並將其放在Views\Shared\EditorTemplates下
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<dynamic>" %> <%@ Import Namespace="System.Web.Mvc.Html" %> <%@ Import Namespace="the extension methods namespace" %> <% Enum model = (Enum)Model; %> <%=Html.DropDownList(model.GetType().Name,model.GetType())%>在您的實體中:
public class Person { [UIHint("Enum")] public GenderEnum Gender{get;set;} } public Enum GenderEnum { [Description("Male Person")] Male, [Description("Female Person")] Female }還有擴展方法:
public static class HtmlHelperExtension { public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type enumType) { List<SelectListItem> list = new List<SelectListItem>(); Dictionary<string, string> enumItems = enumType.GetDescription(); foreach (KeyValuePair<string, string> pair in enumItems) list.Add(new SelectListItem() { Value = pair.Key, Text = pair.Value }); return htmlHelper.DropDownListFor(expression, list); } /// <summary> /// return the items of enum paired with its descrtioption. /// </summary> /// <param name="enumeration">enumeration type to be processed.</param> /// <returns></returns> public static Dictionary<string, string> GetDescription(this Type enumeration) { if (!enumeration.IsEnum) { throw new ArgumentException("passed type must be of Enum type", "enumerationValue"); } Dictionary<string, string> descriptions = new Dictionary<string, string>(); var members = enumeration.GetMembers().Where(m => m.MemberType == MemberTypes.Field); foreach (MemberInfo member in members) { var attrs = member.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attrs.Count() != 0) descriptions.Add(member.Name, ((DescriptionAttribute)attrs[0]).Description); } return descriptions; } }
遲到了,但我希望這對其他人有幫助。理想情況下,您希望所有枚舉都按約定使用您的 Enum 模板,而不是每次都指定 UIHint,您可以通過創建自定義模型元數據提供程序來實現這一點,如下所示:
using System; using System.Collections.Generic; using System.Web.Mvc; public class CustomMetadataProvider : DataAnnotationsModelMetadataProvider { protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName) { var mm = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName); if (modelType.IsEnum && mm.TemplateHint == null) { mm.TemplateHint = "Enum"; } return mm; } }然後只需在 Global.asax.cs 的 Application_Start 方法中註冊它:
ModelMetadataProviders.Current = new CustomMetadataProvider();現在您的所有枚舉屬性將預設使用您的枚舉模板。