我有一个 Html 助手,可以将枚举转换为 SelectList,如下所示:
public static HtmlString EnumSelectListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> forExpression,
object htmlAttributes,
bool blankFirstLine) where TModel : class where TProperty : struct
{
//MS, it its infinite wisdom, does not allow enums as a generic constraint, so we have to check here.
if (!typeof(TProperty).IsEnum) throw new ArgumentException("This helper method requires the specified model property to be an enum type.");
//initialize values
var metaData = ModelMetadata.FromLambdaExpression(forExpression, htmlHelper.ViewData);
var propertyName = metaData.PropertyName;
var propertyValue = htmlHelper.ViewData.Eval(propertyName).ToStringOrEmpty();
//build the select tag
var returnText = string.Format("<select id="{0}" name="{0}"", HttpUtility.HtmlEncode(propertyName));
if (htmlAttributes != null)
{
foreach (var kvp in htmlAttributes.GetType().GetProperties()
.ToDictionary(p => p.Name, p => p.GetValue(htmlAttributes, null)))
{
returnText += string.Format(" {0}="{1}"", HttpUtility.HtmlEncode(kvp.Key),
HttpUtility.HtmlEncode(kvp.Value.ToStringOrEmpty()));
}
}
returnText += ">n";
if (blankFirstLine)
{
returnText += "<option value=""></option>";
}
//build the options tags
foreach (var enumName in Enum.GetNames(typeof(TProperty)))
{
var idValue = ((int)Enum.Parse(typeof(TProperty), enumName, true)).ToString();
var displayValue = enumName;
var titleValue = string.Empty;
returnText += string.Format("<option value="{0}" title="{1}"",
HttpUtility.HtmlEncode(idValue), HttpUtility.HtmlEncode(titleValue));
if (enumName == propertyValue)
{
returnText += " selected="selected"";
}
returnText += string.Format(">{0}</option>n", HttpUtility.HtmlEncode(displayValue));
}
//close the select tag
returnText += "</select>";
return new HtmlString(returnText);
}
我遇到的问题是,枚举的名称中不能有空格,所以如果你有一个单词枚举值以外的内容,你可以得到一些丑陋的选择列表,如下所示:
public enum EmployeeTypes
{
FullTime = 1,
PartTime,
Vendor,
Contractor
}
现在,我有一个好主意,"我知道!我将为此使用数据注释!...所以我让我的枚举看起来像这样:
public enum EmployeeTypes
{
[Display(Name = "Full Time")]
FullTime = 1,
[Display(Name = "Part Time")]
PartTime,
[Display(Name = "Vendor")]
Vendor,
[Display(Name = "Contractor")]
Contractor
}
。但现在我正在挠头如何访问我的帮助程序类中的这些属性。 有人可以让我继续这个吗?
您可以使用循环内的反射从枚举字段中读取DisplayAttribute
:
foreach (var enumName in Enum.GetNames(typeof(TProperty)))
{
var idValue = ((int)Enum.Parse(typeof(TProperty), enumName, true)).ToString();
var displayValue = enumName;
// get the corresponding enum field using reflection
var field = typeof(TProperty).GetField(enumName);
var display = ((DisplayAttribute[])field.GetCustomAttributes(typeof(DisplayAttribute), false)).FirstOrDefault();
if (display != null)
{
// The enum field is decorated with the DisplayAttribute =>
// use its value
displayValue = display.Name;
}
var titleValue = string.Empty;
returnText += string.Format("<option value="{0}" title="{1}"",
HttpUtility.HtmlEncode(idValue), HttpUtility.HtmlEncode(titleValue));
if (enumName == propertyValue)
{
returnText += " selected="selected"";
}
returnText += string.Format(">{0}</option>n", HttpUtility.HtmlEncode(displayValue));
}
我一直
喜欢为 Enum 类创建一个扩展方法来读取 Description 属性,并在您拥有的任何枚举上调用 ToDescription()。 像这样的东西。
public static class EnumExtensions
{
public static String ToDescription(this Enum value)
{
FieldInfo field = value.GetType().GetField(value.ToString());
DescriptionAttribute attribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
return attribute == null ? value.ToString() : attribute.Description;
}
}