Retrieving Display Name Attribute of Enum Members in ASP.NET MVC Razor Views

Nov 19, 2025 · Programming · 23 views · 7.8

Keywords: ASP.NET MVC | Enum Display Names | Razor Views | DisplayAttribute | Reflection Mechanism

Abstract: This article provides an in-depth exploration of how to retrieve display names for enum members decorated with DisplayAttribute in ASP.NET MVC Razor views. Through analysis of the best answer's EnumHelper generic class, it offers a complete implementation solution including reflection mechanisms, resource localization support, and practical applications in Razor views. The article also compares the advantages and disadvantages of different extension methods, providing developers with valuable technical references.

Problem Background and Requirements Analysis

In ASP.NET MVC development, there is often a need to display friendly names for enum values in views, rather than the raw enum member names. Particularly when enum members are decorated with [Display(Name = "...")] attributes, efficiently retrieving these display names becomes a common technical challenge.

Core Solution: EnumHelper Generic Class

Based on the best answer implementation, we create a fully functional EnumHelper<T> generic helper class:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;

public static class EnumHelper<T>
    where T : struct, Enum
{
    public static IList<T> GetValues(Enum value)
    {
        var enumValues = new List<T>();
        
        foreach (FieldInfo fi in value.GetType().GetFields(BindingFlags.Static | BindingFlags.Public))
        {
            enumValues.Add((T)Enum.Parse(value.GetType(), fi.Name, false));
        }
        return enumValues;
    }

    public static T Parse(string value)
    {
        return (T)Enum.Parse(typeof(T), value, true);
    }

    public static IList<string> GetNames(Enum value)
    {
        return value.GetType().GetFields(BindingFlags.Static | BindingFlags.Public)
                   .Select(fi => fi.Name).ToList();
    }

    public static IList<string> GetDisplayValues(Enum value)
    {
        return GetNames(value).Select(obj => GetDisplayValue(Parse(obj))).ToList();
    }

    private static string lookupResource(Type resourceManagerProvider, string resourceKey)
    {
        var resourceKeyProperty = resourceManagerProvider.GetProperty(resourceKey,
            BindingFlags.Static | BindingFlags.Public, null, typeof(string),
            new Type[0], null);
        if (resourceKeyProperty != null)
        {
            return (string)resourceKeyProperty.GetMethod.Invoke(null, null);
        }
        return resourceKey;
    }

    public static string GetDisplayValue(T value)
    {
        var fieldInfo = value.GetType().GetField(value.ToString());
        var descriptionAttributes = fieldInfo.GetCustomAttributes(
            typeof(DisplayAttribute), false) as DisplayAttribute[];

        if (descriptionAttributes == null || descriptionAttributes.Length == 0)
            return value.ToString();

        if (descriptionAttributes[0].ResourceType != null)
            return lookupResource(descriptionAttributes[0].ResourceType, descriptionAttributes[0].Name);

        return descriptionAttributes[0].Name ?? value.ToString();
    }
}

Application in Razor Views

Using EnumHelper<UserPromotion> to display selected items of a flag enum in Razor views:

<ul>
    @foreach (var value in EnumHelper<UserPromotion>.GetValues(UserPromotion.None))
    {
        if ((Model.JobSeeker.Promotion & value) == value)
        {
            var displayName = EnumHelper<UserPromotion>.GetDisplayValue(value);
            <li>@Html.DisplayFor(e => displayName)</li>
        }
    }
</ul>

Technical Implementation Principles Analysis

The core of this solution is based on .NET reflection mechanisms:

Reflection for Field Information: Using GetFields(BindingFlags.Static | BindingFlags.Public) to retrieve all static public fields of the enum, which correspond to the enum's various members.

Attribute Extraction and Processing: Using GetCustomAttributes(typeof(DisplayAttribute), false) method to extract DisplayAttribute properties from field information. This approach ensures graceful fallback to default enum names even when enum members don't have display attributes defined.

Resource Localization Support: By checking the ResourceType property, the solution supports retrieving localized display names from resource files, which is crucial for multilingual applications.

Alternative Solutions Comparison

In addition to the main generic helper class solution, several other implementation approaches exist:

Extension Method Solution:

public static class EnumExtensions
{
    public static string GetDisplayName(this Enum enumValue)
    {
        return enumValue.GetType()
                       .GetMember(enumValue.ToString())
                       .First()
                       .GetCustomAttribute<DisplayAttribute>()
                       ?.GetName();
    }
}

This solution is more concise, using extension method syntax that can be called directly on enum instances. However, it's important to use the GetName() method rather than directly accessing the Name property to ensure proper handling of resource localization.

Generic Attribute Retrieval Solution:

public static TAttribute GetAttribute<TAttribute>(this Enum enumValue) 
        where TAttribute : Attribute
{
    return enumValue.GetType()
                   .GetMember(enumValue.ToString())
                   .First()
                   .GetCustomAttribute<TAttribute>();
}

This solution offers greater flexibility, allowing retrieval of any type of attribute, not just DisplayAttribute.

Performance Considerations and Best Practices

Reflection operations are relatively performance-heavy, especially in frequently called scenarios. Consider the following optimization strategies in practical applications:

Caching Mechanism: Introduce caching to store already parsed enum display names, avoiding repeated reflection operations.

Pre-compilation: Pre-compile display name mappings for all enums during application startup.

Selective Usage: Weigh the convenience of using reflection against performance overhead in performance-sensitive scenarios.

Extended Practical Application Scenarios

Beyond displaying enum values in Razor views, this technique can be applied to:

Dropdown List Binding: Binding enum values and their display names to HTML dropdown lists.

API Response Serialization: Returning enum values with friendly names in Web API responses.

Data Validation Messages: Using enum display names as error messages in data annotation validation.

By properly applying these techniques, you can significantly enhance both the user experience and code maintainability of your applications.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.