在 Razor 页面中迭代枚举值时显示枚举显示名称(在 ASP.NET 核心中)

Displaying enum Display Name when iterating over enum values in Razor page (in ASP.NET Core)

在 Razor 页面(在 ASP.NET 核心中)迭代枚举值时如何显示枚举的显示名称?

剃刀页面:

<label asp-for="Survey.ToldNotToTakeHormones"></label><br />
@foreach (var answer in Enum.GetValues(typeof(AnswerYND)))
{
    <div class="custom-control custom-radio custom-control-inline ">
        <label><input type="radio" asp-for="Survey.ToldNotToTakeHormones" value="@answer" />@answer</label>
    </div>
}

razor 页面背后的代码:

public class EditModel : PageModel
{
    [BindProperty]
    public Survey Survey { get; set; }

调查class:

public class Survey
{
    [Display(Name = "Have you ever been told by a medical professional not to take hormones?")]
    public AnswerYND? ToldNotToTakeHormones { get; set; }

回答YND:

public enum AnswerYND
{ 
    Yes,
    No,
    [Display(Name="Don't Know")]
    DontKnow
}

如果您有兴趣将枚举绑定到控件或字段,并让系统显示枚举的名称,而不是基础值,则有更好的方法来创建您正在寻找的内容。使事情变得复杂的重要一点是,在幕后,system isn't handlingenum 作为 string 从开发人员定义的列表中选取;相反,它默认处理为 Int32.

我在 Stack Overflow 上找到了一些其他答案,可能会帮助您找到更好的解决方案。 This answer explains how you can create your own type-safe class that handles like an enum, but returns the string value that you're looking for. This answer 可能是同一问题的重复,但为该主题添加了更多观点。我使用第一个问题中的代码示例来帮助您了解可以找到您要查找的内容,但可能并不简单。

public class Survey
{
    [Display(Name = "Have you ever been told by a medical professional not to take hormones?")]
    public AnswerYND? ToldNotToTakeHormones { get; set; }
}

public enum AnswerYND
{
    Yes = 1,
    No = 2,
    [Display(Name = "Don't Know")]
    DontKnow = 3
}

class Program
{
    static void Main(string[] args)
    {
        var survey = new Survey();
        Console.WriteLine(survey);
        var options = Enum.GetValues(typeof(AnswerYND));
        for (int i = 0; i < options.Length; i++)
        {
            Console.WriteLine($"Option {i + 1}: {options.GetValue(i)}");
        }
        var choice = Console.ReadLine();
        if (int.TryParse(choice, out int intChoice) && Enum.IsDefined(typeof(AnswerYND), intChoice))
        {
            AnswerYND enumChoice = (AnswerYND)intChoice;
            var name = (enumChoice
                .GetType()
                .GetField(enumChoice.ToString())
                .GetCustomAttributes(typeof(DisplayAttribute), false)
                as DisplayAttribute[])
                .FirstOrDefault()?
                .Name;
            Console.WriteLine($"You selected: {name}");
        }
    }

因此,我能够使用描述而不是显示名称并达到了预期的效果。
我必须创建以下扩展方法:

public static class EnumHelper
{
    public static string GetDescription<T>(this T enumValue)
        where T : struct, IConvertible
    {
        if (!typeof(T).IsEnum)
            return null;

        var description = enumValue.ToString();
        var fieldInfo = enumValue.GetType().GetField(enumValue.ToString());

        if (fieldInfo != null)
        {
            var attrs = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), true);
            if (attrs != null && attrs.Length > 0)
            {
                description = ((DescriptionAttribute)attrs[0]).Description;
            }
        }

        return description;
    }
}

然后我可以通过转换 Enum.GetValues(typeof(AnswerYND)):

的结果来访问 Razor 页面中的扩展方法
<label asp-for="Survey.CurrenltyUsingBirthControl"></label><br />
@foreach (var answer in Enum.GetValues(typeof(AnswerYND)).Cast<AnswerYND>())
{
    <div class="custom-control custom-radio custom-control-inline ">
    <label><input type="radio" asp-for="Survey.CurrenltyUsingBirthControl" value="@answer" />@answer.GetDescription()</label>
    </div>
 }