/ / MVC3 Lista wyboru enumu, przy użyciu adnotacji wyświetlania - asp.net-mvc, asp.net-mvc-3, atrybuty, wyliczenia, adnotacje danych

Lista wyboru Enum MVC3 za pomocą adnotacji na ekranie - asp.net-mvc, asp.net-mvc-3, atrybuty, wyliczenia, adnotacje danych

Mam helper HTML, który konwertuje Enum na SelectList, jak na przykład:

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

Problem w tym, że Enumy nie mogą zawierać spacji w swoich nazwach, więc możesz uzyskać kilka brzydkich list wyboru, jeśli masz coś innego niż wyliczenie jednowyrazowe, takie jak:

public enum EmployeeTypes
{
FullTime = 1,
PartTime,
Vendor,
Contractor
}

Miałem teraz świetny pomysł: "Wiem, użyję do tego funkcji DataAnnotations!" ... więc wyznałem, że moje wyliczenie wygląda następująco:

public enum EmployeeTypes
{
[Display(Name = "Full Time")]
FullTime = 1,
[Display(Name = "Part Time")]
PartTime,
[Display(Name = "Vendor")]
Vendor,
[Display(Name = "Contractor")]
Contractor
}

... ale teraz drapie się po głowie, jak uzyskać dostęp do tych atrybutów w mojej klasie pomocników. Czy ktoś może mnie do tego zachęcić?

Odpowiedzi:

4 dla odpowiedzi № 1

Możesz przeczytać DisplayAttribute z pola wyliczeniowego za pomocą odbicia wewnątrz pętli:

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

0 dla odpowiedzi nr 2

Zawsze byłem fanem tworzenia metody rozszerzenia dla klasy Enum, aby odczytać atrybut Description i po prostu wywoływać ToDescription () na dowolnym wyliczeniu, jakie masz. Coś takiego.

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