我已经为模型中的列定义了[Display(Name = "From Date")]
,并且在asp-for
和@Html.DisplayNameFor()
等标记助手的帮助下从视图中使用它。
但我正在将数据导出到Excel工作表,而该代码在控制器中。现在,为了在excel中设置列标题,我想从[Display(Name = "From Date")]
中获取列名,而不是对其进行硬编码。我该如何使用它?
为了使我的观点更加明确,我现有的代码是:
row.CreateCell(1).SetCellValue("PCard Dt");
现在,我想替换硬编码的字符串";PCard Dt";具有CCD_ 5。
我在谷歌上试过各种答案,但都达不到我的目的。
注释中提到的关键点是您需要System.Reflection来提取DisplayAttribute
。
实现一个扩展方法来从DisplayAttribute
中提取值。
public static class ReflectionExtensions
{
public static string ToName(this PropertyInfo propertyInfo)
{
try
{
object[] attributes = propertyInfo.GetCustomAttributes(typeof(DisplayAttribute), false);
if (attributes != null && attributes.Any())
return ((DisplayAttribute)attributes[0]).Name;
return propertyInfo.Name;
}
catch
{
return propertyInfo.Name;
}
}
}
我在GitHub中写了一个类似的实现。
用下面的方法迭代类中的所有属性并获得DisplayAttribute
的值。
呼叫者
PropertyInfo[] props = typeof(Model).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty);
foreach (PropertyInfo prop in props)
{
string displayName = prop.ToName();
}
使用System.Linq.Expression.的另一种方法
public static class ReflectionExtensions
{
public static string ToNameByExpression<T, P>(Expression<Func<T, P>> propertyExpression) where T : new ()
{
MemberExpression expression = propertyExpression.Body as MemberExpression;
if (expression == null)
return null;
return (expression.Member as PropertyInfo)
.ToName();
}
}
提供表达式以指定所需的属性。
呼叫者
string displayName = ReflectionExtensions.ToNameByExpression((Model m) => m.FromDate);
演示@.NET Fiddle
您可以通过以下方式获得显示名称属性:
public class TestModel
{
[DisplayName("From Date")]
public string FromDate { get; set; }
}
//generic method to get name
private string GetDisplayName<T>(string propertyName)
{
MemberInfo property = typeof(T).GetProperty(propertyName);
var attribute = property.GetCustomAttributes(typeof(DisplayNameAttribute), true)
.Cast<DisplayNameAttribute>().FirstOrDefault();
return attribute?.DisplayName ?? propertyName;
}
//get display name
var displayName = GetDisplayName<TestModel>(nameof(TestModel.FromDate));