如何获取DataAnnotation中Display特性的名称列表
我来给你捋捋怎么从这个带Data Annotations的类里提取Display特性的Name属性列表哈,其实用.NET的反射就能轻松搞定,给你几个实用的实现方式:
首先先把你给出的类补全(方便测试):
internal class TVSystemViewData : BaseViewData { [Display(Name = "BoxType", Description = "")] public string BoxType { get; set; } [Display(Name = "BoxVendor", Description = "")] public string BoxVendor { get; set; } [Display(Name = "ClientId", Description = "")] public string ClientId { get; set; } [Display(Name = "HostName", Description = "")] public string HostName { get; set; } } internal class BaseViewData { }
方式一:基础反射写法(适合理解原理)
这种写法一步步拆解,清晰明了:
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Reflection; public static List<string> GetDisplayNames(Type type) { var displayNames = new List<string>(); // 获取类的所有公共实例属性,如果要包含基类的属性,记得加上BindingFlags.FlattenHierarchy var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var prop in properties) { // 提取当前属性上的Display特性 var displayAttr = prop.GetCustomAttribute<DisplayAttribute>(); // 只有当特性存在且Name不为空时,才添加到列表 if (displayAttr != null && !string.IsNullOrEmpty(displayAttr.Name)) { displayNames.Add(displayAttr.Name); } // 可选:如果属性没有Display特性,你可以选择用属性名作为备选 // else // { // displayNames.Add(prop.Name); // } } return displayNames; } // 使用示例: var names = GetDisplayNames(typeof(TVSystemViewData)); // 结果就是 ["BoxType", "BoxVendor", "ClientId", "HostName"]
方式二:LINQ简化写法(更简洁)
如果你喜欢更紧凑的代码,用LINQ可以一行搞定核心逻辑:
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Reflection; public static List<string> GetDisplayNamesLinq(Type type) { return type.GetProperties(BindingFlags.Public | BindingFlags.Instance) .Select(prop => prop.GetCustomAttribute<DisplayAttribute>()) .Where(attr => attr != null && !string.IsNullOrEmpty(attr.Name)) .Select(attr => attr.Name) .ToList(); } // 使用方式和上面完全一样 var names = GetDisplayNamesLinq(typeof(TVSystemViewData));
几个小提醒
- 要是需要包含基类BaseViewData里的属性,把
GetProperties的BindingFlags改成BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy就行 - 有些属性可能没加Display特性,或者Name是空的,你可以根据自己的需求决定是跳过还是用属性名替代
- 不管是.NET Framework还是.NET Core/.NET 5+,这些代码都能直接用,API是兼容的
内容的提问来源于stack exchange,提问作者Fabio Santos
相关产品推荐
相关产品推荐

