2012-02-17 29 views
23

tôi có phương pháp helper sau trong một lớp học ViewModelBase, được thừa hưởng bởi mô hình điểm khác:tên hiển thị MVC.net get enum theo quan điểm mà không cần phải tham khảo kiểu enum theo quan điểm

public string GetEnumName<T>(Enum value) 
     { 
      Type enumType = typeof(T); 
      var enumValue = Enum.GetName(enumType, value); 
      MemberInfo member = enumType.GetMember(enumValue)[0]; 

      var attrs = member.GetCustomAttributes(typeof(DisplayAttribute), false); 
      var outString = ((DisplayAttribute)attrs[0]).Name; 

      if (((DisplayAttribute)attrs[0]).ResourceType != null) 
      { 
       outString = ((DisplayAttribute)attrs[0]).GetName(); 
      } 

      return outString; 
     } 

sau đó tôi gọi này từ quan điểm như thế này:

<p> 
@{var rel = Model.GetEnumDisplayName<Enums.wheteverEnum>(Model.wheteverEnum); } 
@rel 
</p> 

Câu hỏi là - tôi có thể làm việc phương pháp này vì vậy tôi không phải nói với nó kiểu của enum? Về cơ bản tôi muốn todo này cho tất cả enum s:

@ Model.GetEnumDisplayName (Model.wheteverEnum)

Không typeof, không T, không cần phải thêm một tham chiếu đến namespace Enums trong Xem ...

Có thể?

Trả lời

54

Bạn có thể dễ dàng loại bỏ các tham số kiểu và làm cho nó trở thành một phương pháp khuyến nông.

public static string DisplayName(this Enum value) 
    { 
     Type enumType = value.GetType(); 
     var enumValue = Enum.GetName(enumType, value); 
     MemberInfo member = enumType.GetMember(enumValue)[0]; 

     var attrs = member.GetCustomAttributes(typeof(DisplayAttribute), false); 
     var outString = ((DisplayAttribute)attrs[0]).Name; 

     if (((DisplayAttribute)attrs[0]).ResourceType != null) 
     { 
      outString = ((DisplayAttribute)attrs[0]).GetName(); 
     } 

     return outString; 
    } 

    @Model.wheteverEnum.DisplayName() 
+0

+1 Rất tốt. Nó đã sử dụng mã gốc cộng với việc triển khai mã của phương pháp mở rộng bao gồm cách gọi nó là – Nope

+2

Đối với c Vì vậy, bạn nên thêm một kiểm tra rằng có bất kỳ 'DisplayAttributes' nào được áp dụng cho giá trị enum và trả về' value.ToString() 'làm mặc định nếu không có bất kỳ giá trị nào. Nếu không, bạn sẽ nhận được 'IndexOutOfRangeException' khi bạn gọi' ((DisplayAttribute) attrs [0]). Tên ' – flipchart

+0

Nếu ai đó cố gắng gọi từ controller: DisplayName ((MyEnum) id); –

7

Bạn không thể viết thư này làm phương thức tiện ích mở rộng? Một cái gì đó giống như ...

public static class EnumExtensions 
{ 
    public static string ToDescription(this Enum e) 
    { 
    var attributes = (DisplayAttribute[])e.GetType().GetField(e.ToString()).GetCustomAttributes(typeof(DisplayAttribute), false); 
    return attributes.Length > 0 ? attributes[0].Description : string.Empty; 
    } 
} 

Cách sử dụng:

@Model.WhateverEnum.ToDescription(); 
0

Đây là phương pháp mở rộng mà tôi đã viết để thực hiện điều này ... nó có thêm một chút logic để phân tích tên Enum và chia nhỏ bằng chữ in hoa. Bạn có thể ghi đè lên bất kỳ tên bằng cách sử dụng Display Thuộc tính

public static TAttribute GetAttribute<TAttribute>(this ICustomAttributeProvider parameterInfo) where TAttribute : Attribute 
{ 
    object[] attributes = parameterInfo.GetCustomAttributes(typeof(TAttribute), false); 
    return attributes.Length > 0 ? (TAttribute)attributes[0] : null; 
} 
public static bool HasAttribute<TAttribute>(this ICustomAttributeProvider parameterInfo) where TAttribute : Attribute 
{ 
    object[] attributes = parameterInfo.GetCustomAttributes(typeof(TAttribute), false); 
    return attributes.Length > 0 ? true : false; 
} 

public static string ToFriendlyEnum(this Enum type) 
{ 
    return type.GetType().HasAttribute<DescriptionAttribute>() ? type.GetType().GetAttribute<DescriptionAttribute>().Description : type.ToString().ToFriendlyEnum(); 
} 

public static string ToFriendlyEnum(this string value) 
{ 
    char[] chars = value.ToCharArray(); 
    string output = string.Empty; 

    for (int i = 0; i < chars.Length; i++) 
    { 
     if (i <= 0 || chars[i - 1].ToString() != chars[i - 1].ToString().ToUpper() && chars[i].ToString() != chars[i].ToString().ToLower()) 
     { 
      output += " "; 
     } 

     output += chars[i]; 
    } 

    return output.Trim(); 
} 

Các phương pháp khuyến nông GetAttribute có thể là hơi quá mức cần thiết, nhưng tôi sử dụng chúng ở những nơi khác trong các dự án của tôi, vì vậy họ đã sử dụng lại khi tôi đã viết phần mở rộng Enum của tôi. Bạn có thể dễ dàng kết hợp chúng trở lại vào ToFriendlyEnum (loại Enum này) phương pháp

5

Thật tuyệt @jrummell!

Tôi đã thêm một tinh chỉnh nhỏ dưới đây mà chụp các kịch bản mà một enum không có liên quan đến Display thuộc tính (hiện tại nó ném một ngoại lệ)

/// <summary> 
/// Gets the DataAnnotation DisplayName attribute for a given enum (for displaying enums values nicely to users) 
/// </summary> 
/// <param name="value">Enum value to get display for</param> 
/// <returns>Pretty version of enum (if there is one)</returns> 
/// <remarks> 
/// Inspired by : 
///  http://stackoverflow.com/questions/9328972/mvc-net-get-enum-display-name-in-view-without-having-to-refer-to-enum-type-in-vi 
/// </remarks> 
public static string DisplayFor(this Enum value) { 
    Type enumType = value.GetType(); 
    var enumValue = Enum.GetName(enumType, value); 
    MemberInfo member = enumType.GetMember(enumValue)[0]; 
    string outString = ""; 

    var attrs = member.GetCustomAttributes(typeof(DisplayAttribute), false); 
    if (attrs.Any()) { 
     var displayAttr = ((DisplayAttribute)attrs[0]); 

     outString = displayAttr.Name; 

     if (displayAttr.ResourceType != null) { 
      outString = displayAttr.GetName(); 
     } 
    } else { 
     outString = value.ToString(); 
    } 

    return outString; 
} 
0

xét, giải quyết đề nghị không làm việc cho tôi với MVC3: để người trợ giúp dưới đây là tốt .:

public static string GetEnumDescription(this Enum value) 
    { 
     Type type = value.GetType(); 
     string name = Enum.GetName(type, value); 
     if (name != null) 
     { 
      FieldInfo field = type.GetField(name); 
      if (field != null) 
      { 
       string attr = field.GetCustomAttributesData()[0].NamedArguments[0].TypedValue.Value.ToString(); 
       if (attr == null) 
       { 
        return name; 
       } 
       else 
       { 
        return attr; 
       } 
      } 
     } 
     return null; 
    } 
1

Câu trả lời của @jrummell trong VB.NET cho một vài người trong chúng ta ...

Module ModuleExtension 

    <Extension()> 
    Public Function DisplayName(ByVal value As System.Enum) As String 

     Dim enumType As Type = value.GetType() 
     Dim enumValue = System.Enum.GetName(enumType, value) 
     Dim member As MemberInfo = enumType.GetMember(enumValue)(0) 

     Dim attrs = member.GetCustomAttributes(GetType(DisplayAttribute), False) 
     Dim outString = CType(attrs(0), DisplayAttribute).Name 

     If (CType(attrs(0), DisplayAttribute).ResourceType IsNot Nothing) Then 
      outString = CType(attrs(0), DisplayAttribute).GetName() 
     End If 

     Return outString 
    End Function 


End Module 
1

cho bất cứ ai có thể đạt được cho câu hỏi này, tôi thấy điều này dễ dàng hơn nhiều so với bất cứ điều gì khác: https://www.codeproject.com/articles/776908/dealing-with-enum-in-mvc

Chỉ cần tạo một thư mục "DisplayTemplate" dưới "Views \ Shared", và tạo ra một chế độ xem trống (Đặt tên là "Enum") trong thư mục mới "DisplayTemplate" và sao chép mã này vào thư mục "

@model Enum 

@if (EnumHelper.IsValidForEnumHelper(ViewData.ModelMetadata)) 
{ 
    // Display Enum using same names (from [Display] attributes) as in editors 
    string displayName = null; 
    foreach (SelectListItem item in EnumHelper.GetSelectList(ViewData.ModelMetadata, (Enum)Model)) 
    { 
     if (item.Selected) 
     { 
      displayName = item.Text ?? item.Value; 
     } 
    } 

    // Handle the unexpected case that nothing is selected 
    if (String.IsNullOrEmpty(displayName)) 
    { 
     if (Model == null) 
     { 
      displayName = String.Empty; 
     } 
     else 
     { 
      displayName = Model.ToString(); 
     } 
    } 

    @Html.DisplayTextFor(model => displayName) 
} 
else 
{ 
    // This Enum type is not supported. Fall back to the text. 
    @Html.DisplayTextFor(model => model) 
} 
Các vấn đề liên quan