如何在 asp.net mvc 中使用带有 DescriptionAttribute 的枚举
how to use enum with DescriptionAttribute in asp.net mvc
我是 asp.net MVC 的新手。我正在尝试在我的视图页面上使用下拉控件,它从枚举中填充。我还想为下拉值添加自定义描述。我搜索了很多示例,但没有人 post 了解如何在视图页面上填充描述。这是我的代码:
视图模型:
public enum SearchBy
{
[Description("SID/PID")]
SID = 1,
[Description("Name")]
Name,
[Description("Birth Date")]
DOB,
[Description("Cause#")]
Cause
}
Index.cshtml
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group form-inline">
@Html.LabelFor(model => model.searchBy, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EnumDropDownListFor(model => model.searchBy, "Search By", htmlAttributes: new { @class = "form-control" })
@Html.TextBox("searchByVal", null, htmlAttributes: new { @placeholder = "SID / PID ", @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @placeholder = "First Name", @class = "form-control" } })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @placeholder = "Last Name", @class = "form-control" } })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.DOB, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.DOB, new { htmlAttributes = new { @placeholder = "Birth Date", @class = "form-control" } })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.CauseNumber, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.CauseNumber, new { htmlAttributes = new { @placeholder = "Cause#", @class = "form-control" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Search" class="btn btn-block btn-primary" />
</div>
</div>
</div>
它没有像我的 SearchBy 枚举中提到的那样填充描述字段。看这里的图片。
http://postimg.org/image/phdxgocj7/
请帮助我,我在哪里犯了错误。谢谢
更新:
我从 Nico 那里得到了解决方案。我对此进行了一些研究。我正在用解决方案更新这个 post 因为它可能对其他不熟悉 MVC 的人有用
http://weblogs.asp.net/jongalloway//looking-at-asp-net-mvc-5-1-and-web-api-2-1-part-1-overview-and-enums
谢谢大家。享受编码..
Html 助手 EnumDropDownListFor
或 EnumDropDownList
不考虑 enum
成员的 Description
属性装饰。但是通过查看源代码:
枚举下拉列表助手:
https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/SelectExtensions.cs
枚举助手类:
https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/EnumHelper.cs
上面的枚举助手 类 用于将 Enum
转换为 List<SelectListItem>
。来自以下代码:
// Return non-empty name specified in a [Display] attribute for the given field, if any; field's name otherwise
private static string GetDisplayName(FieldInfo field)
{
DisplayAttribute display = field.GetCustomAttribute<DisplayAttribute>(inherit: false);
if (display != null)
{
string name = display.GetName();
if (!String.IsNullOrEmpty(name))
{
return name;
}
}
return field.Name;
}
您可以看到,在方法 GetDisplayName
中,它检查 enum
成员上是否存在 DisplayAttribute
。如果 display 属性存在,则名称设置为 DisplayAttribute.GetName()
方法的结果。
将这些放在一起我们可以修改 enum
以使用 DisplayAttribute
而不是 DescriptionAttribute
并将 Name
属性 设置为您的值希望展示。
public enum SearchBy
{
[Display(Name = "SID/PID")]
SID = 1,
[Display(Name = "Name")]
Name,
[Display(Name = "Birth Date")]
DOB,
[Display(Name = "Cause#")]
Cause
}
这会给你想要的结果。
希望这对您有所帮助。
给定:
public enum MyEnum
{
[Description("This is the description if my member A")]
A,
[Description("This is the description if my member B")]
B
}
我个人使用此扩展方法从我的枚举中获取描述:
public static string GetDescription(this Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0)
{
return attributes[0].Description;
}
else
{
return value.ToString();
}
}
要使用它:
MyEnum.A.GetDescription();
希望对您有所帮助。
我创建了一个助手 class 来尝试不同类型的属性。我需要它,因为我正在使用 bootstrap 和 https://github.com/civicsource/enums and https://silviomoreto.github.io/bootstrap-select/
public static class EnumHelper<T>
{
static EnumHelper()
{
var enumType = typeof(T);
if (!enumType.IsEnum) { throw new ArgumentException("Type '" + enumType.Name + "' is not an enum"); }
}
public static string GetEnumDescription(T value)
{
var fi = typeof(T).GetField(value.ToString());
var attributes = (DescriptionAttribute[]) fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : value.ToString();
}
public static IEnumerable<SelectListItem> GetSelectList()
{
var groupDictionary = new Dictionary<string, SelectListGroup>();
var enumType = typeof(T);
var fields = from field in enumType.GetFields()
where field.IsLiteral
select field;
foreach (var field in fields)
{
var display = field.GetCustomAttribute<DisplayAttribute>(false);
var description = field.GetCustomAttribute<DescriptionAttribute>(false);
var group = field.GetCustomAttribute<CategoryAttribute>(false);
var text = display?.GetName() ?? display?.GetShortName() ?? display?.GetDescription() ?? display?.GetPrompt() ?? description?.Description ?? field.Name;
var value = field.Name;
var groupName = display?.GetGroupName() ?? group?.Category ?? string.Empty;
if (!groupDictionary.ContainsKey(groupName)) { groupDictionary.Add(groupName, new SelectListGroup { Name = groupName }); }
yield return new SelectListItem
{
Text = text,
Value = value,
Group = groupDictionary[groupName],
};
}
}
}
你这样称呼它:
<div class="form-group">
@Html.LabelFor(model => model.Address.State, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-sm-4">
@Html.DropDownListFor(model => model.Address.State, EnumHelper<StateProvince>.GetSelectList(), new { @class = "selectpicker show-menu-arrow", data_live_search = "true" })
@Html.ValidationMessageFor(model => model.Address.State, "", new { @class = "text-danger" })
</div>
</div>
如果您使用的是 .Net Framework 4.0
或更新版本,则无需创建助手 class。
您可以将 Display
属性与 EnumDropDownListFor
结合使用
public enum SearchBy
{
[Display(Name = "SID/PID")]
SID = 1,
[Display(Name = "Name")]
Name,
[Display(Name = "Birth Date")]
DOB,
[Display(Name = "Cause#")]
Cause
}
在您看来:
@Html.EnumDropDownListFor(model => model.SearchBy, "Search By", new { @class = "form-control" })
微软文档:
我是 asp.net MVC 的新手。我正在尝试在我的视图页面上使用下拉控件,它从枚举中填充。我还想为下拉值添加自定义描述。我搜索了很多示例,但没有人 post 了解如何在视图页面上填充描述。这是我的代码:
视图模型:
public enum SearchBy
{
[Description("SID/PID")]
SID = 1,
[Description("Name")]
Name,
[Description("Birth Date")]
DOB,
[Description("Cause#")]
Cause
}
Index.cshtml
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group form-inline">
@Html.LabelFor(model => model.searchBy, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EnumDropDownListFor(model => model.searchBy, "Search By", htmlAttributes: new { @class = "form-control" })
@Html.TextBox("searchByVal", null, htmlAttributes: new { @placeholder = "SID / PID ", @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @placeholder = "First Name", @class = "form-control" } })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @placeholder = "Last Name", @class = "form-control" } })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.DOB, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.DOB, new { htmlAttributes = new { @placeholder = "Birth Date", @class = "form-control" } })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.CauseNumber, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.CauseNumber, new { htmlAttributes = new { @placeholder = "Cause#", @class = "form-control" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Search" class="btn btn-block btn-primary" />
</div>
</div>
</div>
它没有像我的 SearchBy 枚举中提到的那样填充描述字段。看这里的图片。 http://postimg.org/image/phdxgocj7/ 请帮助我,我在哪里犯了错误。谢谢
更新: 我从 Nico 那里得到了解决方案。我对此进行了一些研究。我正在用解决方案更新这个 post 因为它可能对其他不熟悉 MVC 的人有用 http://weblogs.asp.net/jongalloway//looking-at-asp-net-mvc-5-1-and-web-api-2-1-part-1-overview-and-enums
谢谢大家。享受编码..
Html 助手 EnumDropDownListFor
或 EnumDropDownList
不考虑 enum
成员的 Description
属性装饰。但是通过查看源代码:
枚举下拉列表助手: https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/SelectExtensions.cs
枚举助手类: https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/EnumHelper.cs
上面的枚举助手 类 用于将 Enum
转换为 List<SelectListItem>
。来自以下代码:
// Return non-empty name specified in a [Display] attribute for the given field, if any; field's name otherwise
private static string GetDisplayName(FieldInfo field)
{
DisplayAttribute display = field.GetCustomAttribute<DisplayAttribute>(inherit: false);
if (display != null)
{
string name = display.GetName();
if (!String.IsNullOrEmpty(name))
{
return name;
}
}
return field.Name;
}
您可以看到,在方法 GetDisplayName
中,它检查 enum
成员上是否存在 DisplayAttribute
。如果 display 属性存在,则名称设置为 DisplayAttribute.GetName()
方法的结果。
将这些放在一起我们可以修改 enum
以使用 DisplayAttribute
而不是 DescriptionAttribute
并将 Name
属性 设置为您的值希望展示。
public enum SearchBy
{
[Display(Name = "SID/PID")]
SID = 1,
[Display(Name = "Name")]
Name,
[Display(Name = "Birth Date")]
DOB,
[Display(Name = "Cause#")]
Cause
}
这会给你想要的结果。
希望这对您有所帮助。
给定:
public enum MyEnum
{
[Description("This is the description if my member A")]
A,
[Description("This is the description if my member B")]
B
}
我个人使用此扩展方法从我的枚举中获取描述:
public static string GetDescription(this Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0)
{
return attributes[0].Description;
}
else
{
return value.ToString();
}
}
要使用它:
MyEnum.A.GetDescription();
希望对您有所帮助。
我创建了一个助手 class 来尝试不同类型的属性。我需要它,因为我正在使用 bootstrap 和 https://github.com/civicsource/enums and https://silviomoreto.github.io/bootstrap-select/
public static class EnumHelper<T>
{
static EnumHelper()
{
var enumType = typeof(T);
if (!enumType.IsEnum) { throw new ArgumentException("Type '" + enumType.Name + "' is not an enum"); }
}
public static string GetEnumDescription(T value)
{
var fi = typeof(T).GetField(value.ToString());
var attributes = (DescriptionAttribute[]) fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : value.ToString();
}
public static IEnumerable<SelectListItem> GetSelectList()
{
var groupDictionary = new Dictionary<string, SelectListGroup>();
var enumType = typeof(T);
var fields = from field in enumType.GetFields()
where field.IsLiteral
select field;
foreach (var field in fields)
{
var display = field.GetCustomAttribute<DisplayAttribute>(false);
var description = field.GetCustomAttribute<DescriptionAttribute>(false);
var group = field.GetCustomAttribute<CategoryAttribute>(false);
var text = display?.GetName() ?? display?.GetShortName() ?? display?.GetDescription() ?? display?.GetPrompt() ?? description?.Description ?? field.Name;
var value = field.Name;
var groupName = display?.GetGroupName() ?? group?.Category ?? string.Empty;
if (!groupDictionary.ContainsKey(groupName)) { groupDictionary.Add(groupName, new SelectListGroup { Name = groupName }); }
yield return new SelectListItem
{
Text = text,
Value = value,
Group = groupDictionary[groupName],
};
}
}
}
你这样称呼它:
<div class="form-group">
@Html.LabelFor(model => model.Address.State, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-sm-4">
@Html.DropDownListFor(model => model.Address.State, EnumHelper<StateProvince>.GetSelectList(), new { @class = "selectpicker show-menu-arrow", data_live_search = "true" })
@Html.ValidationMessageFor(model => model.Address.State, "", new { @class = "text-danger" })
</div>
</div>
如果您使用的是 .Net Framework 4.0
或更新版本,则无需创建助手 class。
您可以将 Display
属性与 EnumDropDownListFor
public enum SearchBy
{
[Display(Name = "SID/PID")]
SID = 1,
[Display(Name = "Name")]
Name,
[Display(Name = "Birth Date")]
DOB,
[Display(Name = "Cause#")]
Cause
}
在您看来:
@Html.EnumDropDownListFor(model => model.SearchBy, "Search By", new { @class = "form-control" })
微软文档: