I have defined [Display(Name = "From Date")]
for columns in a Model and I am using it from a View with the help of tag helpers like asp-for
and @Html.DisplayNameFor()
.
But I am exporting data to an Excel sheet, and that code is in a controller. Now to set the column header in excel I want to take column names from [Display(Name = "From Date")]
instead of hard coding it.
How can I use it?
To make my point more clear, my existing code is:
row.CreateCell(1).SetCellValue("PCard Dt");
Now, I want to replace the hard-coded string "PCard Dt" with [Display(Name = "From Date")]
.
I tried various answers on Google, but it's not serving my purpose.
CodePudding user response:
The key point mentioned in the comment is you need System.Reflection to extract the DisplayAttribute
.
Implement an extension method to extract the value from 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;
}
}
}
I wrote a similar implementation in GitHub.
With the below way to iterate all properties in class and get the value of DisplayAttribute
.
Caller
PropertyInfo[] props = typeof(Model).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty);
foreach (PropertyInfo prop in props)
{
string displayName = prop.ToName();
}
Another approach to work with 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();
}
}
Provide the expression to specify the property that you want.
Caller
string displayName = ReflectionExtensions.ToNameByExpression((Model m) => m.FromDate);
CodePudding user response:
You get display name attribute by this way:
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));