C# 如何循环使用DataAnnotation’;是否在MVC视图中显示名称?

C# 如何循环使用DataAnnotation’;是否在MVC视图中显示名称?,c#,asp.net-mvc,razor,ef-code-first,data-annotations,C#,Asp.net Mvc,Razor,Ef Code First,Data Annotations,我想访问模型类的DataAnnotation的DisplayName和类似的GroupName,然后在MVC视图中循环。例如,让我说我的一个模型属性如下 public class Person { [Display(Name="Home Phone",GroupName="Home")] public string HomePhone { get; set; } [Display(Name = "Home Address", GroupName = "Home")]

我想访问模型类的
DataAnnotation
DisplayName
和类似的
GroupName
,然后在MVC视图中循环。例如,让我说我的一个模型属性如下

public class Person
{
    [Display(Name="Home Phone",GroupName="Home")]
    public string HomePhone { get; set; }
    [Display(Name = "Home Address", GroupName = "Home")]
    public string HomeAddress { get; set; }
    [Display(Name = "Office Phone", GroupName = "Office")]
    public string OfficePhone { get; set; }
    [Display(Name = "Office Address", GroupName = "Office")]
    public string OfficeAddress { get; set; }
}
如何在类似的
GroupName
中循环查看
DisplayName

结果应该是这样的,

  • 家庭电话
  • 家庭住址
  • 办公室

  • 办公室电话
  • 办公地址

  • 可以使用使用表达式读取属性的DisplayName和GroupName属性的函数创建帮助器类:

        public static string GetDisplayName<T, TProp>(Expression<Func<T, TProp>> expression)
        {
            MemberExpression body = GetMemberExpression(expression);
            DisplayNameAttribute attribute = body.Member.GetCustomAttributes(typeof(DisplayNameAttribute), true).Cast<DisplayNameAttribute>().Single();
            return attribute.DisplayName;
        }
    
    公共静态字符串GetDisplayName(表达式)
    {
    MemberExpression body=GetMemberExpression(表达式);
    DisplayNameAttribute属性=body.Member.GetCustomAttributes(typeof(DisplayNameAttribute),true).Cast().Single();
    返回attribute.DisplayName;
    }
    
    在你的剃须刀中使用:

    <span>@ReflectionHelper.GetDisplayName((Person p) => p.HomePhone)</span>
    
    @ReflectionHelper.GetDisplayName((个人p)=>p.HomePhone)
    
    为了便于阅读,我建议您在控制器中根据Person类使用此帮助程序准备一个字典(或其他模型),并在视图中呈现该字典(或其他模型),而不是在razor中使用帮助程序。

    我找到了解决方案

    public List<string> GetDisplayNamesGrouped(Type ClassName, string GroupName)
        {
            List<string> DisplayNameList = new List<string>();
            var properties = ClassName.GetProperties();
            foreach (var property in properties)
            {
                var displayAttribute = property.GetCustomAttributes(typeof(DisplayAttribute), true).FirstOrDefault() as DisplayAttribute;
                string displayName = property.Name;
                if (displayAttribute != null)
                {
                    if (displayAttribute.GroupName == GroupName)
                    {
                        displayName = displayAttribute.Name;
                        DisplayNameList.Add(displayName);
                    }
                }
            }
            return DisplayNameList;
        }
    

    你让自己的生活很艰难。为什么不将它们分组到单独的对象中,例如
    OfficeModel
    HomeModel
    ?更干净。@mattytomo我支持你所说的,他可以更好地简单地将其制作为两个对象,以提高可读性和可维护性。在这里,我的使用目的是不同的,我想实现一个类似于下拉列表的功能,为用户提供选择列名的选项。看看这篇文章:已经有一个帮助程序可以做到这一点:
    @Html.DisplayNameFor()
    @Silvex我尝试了你的代码片段,但它只是返回
    DisplayName
    ,而不管
    GroupName
    。在我的例子中,
    DisplayName
    应该列出
    GroupName=Office
    的位置。如何检查这种情况?
    var Home = GetDisplayNamesGrouped(typeof(Person), "Home");
    var Office = GetDisplayNamesGrouped(typeof(Person), "Office");