c# - 如何访问字段的 System.ComponentModel.DataAnnotations 显示名称属性

标签 c# asp.net-mvc-3

我有一个 View 模型,其中属性具有显示名称。我现在正在制作一个 Excel 工作表,其中包含与网页中的网格相同的数据。我正在使用 closed xml (使用 openxml)在服务器上创建 Excelsheet,并在他们想要将数据下载为 Excel 时将其发送到网络客户端。 当我在 Excel openxml 流中写入标题行时,我想重新使用已经定义的显示名称。但我不知道该调用什么。

这是显示名称的示例。 (例如,我只使用了两个,实际还有更多的列):

 using System.ComponentModel.DataAnnotations;
 public class DCArrival : IDCArrival
 { 
   [Display(Name = "Via Transit")]
   public String LocationType { get; set; }
   [Display(Name = "Currency")]
   String CurrencyISOCode { get;  }
 }

然后我想在创建标题行时使用这个显示名称。标记试图解释我想要掌握的内容的伪代码:

private MemoryStream CreateExcelFile(ICollection<DCArrival> dcArrToShow
, QueryStrInput   queryStrInput)
    {
        try
        {
            // Create an Excel Workbook
            XLWorkbook wb = new XLWorkbook();
            // Add the worksheet with  data 
            IXLWorksheet ws = wb.Worksheets.Add("New Worksheet");
            // Add my data that was displayed in the html table ... 
            ws.Cell(1, 1).SetValue("Hello World");
           //Add Header row. By taking a object in the collection and figure out its
           // display name
           DCArrival firstRow = dcArrToShow.First();
           // Here comes my problem. Here is my dream up mockup code

            ws.Cell(2,1).Value = firstRow.LocationType.DisplayAttribute.GetName()
            ws.Cell(2,2).Value = firstRow.CurrencyISOCode.DisplayAttribute.GetName()
           // back to reality
           //this is how easy I can get all data from Collection
            ws.Cell(3, 1).Value = dcArrToShow.AsEnumerable();
          // All done
            MemoryStream ms = new MemoryStream();
            wb.SaveAs(ms);
            return ms;
        }
        catch (Exception e)
        {
            string errmsg = String.Format("Failed to create Excel file: {0}",
          e.Message);
            throw new Exception(errmsg, e);
        }

我看过 http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayattribute.aspx 但我不明白我是如何掌握它的。 我知道当您使用普通的 mvc 3 html 渲染时,这对您来说是神奇的修复。当我用谷歌搜索这些概念时,我被淹没在想要解释 MVC 3 中基本验证的博客中。

最佳答案

您可以从模型元数据中检索它:

ws.Cell(2.1).Value = ModelMetadata.FromLambdaExpression<DCArrival, string>(x => x.LocationType, new ViewDataDictionary<DCArrival>(firstRow)).DisplayName;

或者写一个扩展方法:

public static class ModelMetadataExtensions
{
    public static string GetName<TModel, TProperty>(this TModel model, Expression<Func<TModel, TProperty>> ex)
    {
        return ModelMetadata
            .FromLambdaExpression<TModel, TProperty>(ex, new ViewDataDictionary<TModel>(model))
            .DisplayName;
    }
}

然后:

ws.Cell(2.1).Value = firstRow.GetName(x => x.LocationType);
ws.Cell(2.2).Value = firstRow.GetName(x => x.CurrencyISOCode);

更新:

根据评论部分中表达的新要求,为了遍历所有属性并读取显示属性,您可以使用以下内容:

var properties = typeof(DCArrival).GetProperties(); 
foreach (var property in properties) 
{
    var displayAttribute = property
        .GetCustomAttributes(typeof(DisplayAttribute), true)
        .FirstOrDefault() as DisplayAttribute;
    string displayName = property.Name;
    if (displayAttribute != null)
    {
        displayName = displayAttribute.Name;
    }

    // TODO: do something with the display name for this property
} 

关于c# - 如何访问字段的 System.ComponentModel.DataAnnotations 显示名称属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9293258/

相关文章:

c# - MongoDB C#驱动多字段查询

jquery - MVC 模型绑定(bind)期间日月反转

c# - 在一个 CMS/多个网站系统中管理数据库的最佳方法是什么

asp.net-mvc-3 - 无法解析 : User. Core.Entities.Teacher 的属性 : Harrods. Full_Name

asp.net - 当无效参数传递到 ASP.NET MVC Controller 时,如何返回 404 状态?

model-view-controller - BindModel() 实现应该做什么?

c# - 将一个对象的方法传递给另一个对象是否使第一个对象保持事件状态?

c# - StackOverflowException 通过使用具有协变泛型参数的显式接口(interface)实现

C# 文本框拼写检查器检查所有大写单词

c# - 使用 DacFX 对 DACPAC 中的 View 进行代码分析验证