2015-06-22 106 views
4

我有下面的類將數據導出到CSV:如何從PARAMS獲得屬性名稱功能<T, string> [] lambda表達式

public class CsvResult<T> : FileResult where T : class 
{ 
    private const string SEPARATOR = ","; 

    public IEnumerable<T> Data { get; private set; } 
    public Func<T, string>[] Columns { get; private set; } 

    public CsvResult(IEnumerable<T> data, params Func<T, string>[] columns) 
     : base("text/csv") 
    { 
     Data = data; 
     Columns = columns; 
     FileDownloadName = "Export.csv"; 
    } 

    protected override void WriteFile(HttpResponseBase response) 
    { 
     response.ContentType = "text/csv"; 
     response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", FileDownloadName)); 

     WriteColumns(response); 
     WriteData(response); 
    } 

    private void WriteData(HttpResponseBase response) 
    { 
     foreach (var dataItem in Data) 
     { 
      foreach (var column in Columns) 
       WriteCsvCell(response, column(dataItem)); 
      response.Write(Environment.NewLine); 
     } 
    } 

    private void WriteColumns(HttpResponseBase response) 
    { 
     foreach (var column in Columns) 
      WriteCsvCell(response, column.ToString()); 

     response.Write(Environment.NewLine); 
    } 

    private void WriteCsvCell(HttpResponseBase response, string text) 
    { 
     // Surround with quotes + escape quotes within the text 
     response.Write("\"" + text.Replace("\"", "\"\"") + "\""); 
     response.Write(SEPARATOR); 
    } 
} 

,我用這樣的:

 if (format == RenderFormat.Csv) 
      return new CsvResult<User>(
       users, 
       u => u.FirstName, 
       u => u.LastName); 

而且我得到:

"System.Func`2[HDO.Application.Model.Models.User,System.String]","System.Func`2[HDO.Application.Model.Models.User,System.String]", 
"FirstName1","LastName1", 
"FirstName2","LastName2", 

等。

我的結果,我想在這個例子中使用,例如名字和姓氏的屬性名作爲列標題:

"FirstName", "LastName", <--------Headers 
"FirstName1","LastName1", <---------Data row 1 
"FirstName2","LastName2",<---------Data row 2 

關於如何修改lambda表達式的任何線索acomplish呢?

回答

2

而不是Func<>,您需要將參數類型更改爲Expression<Func<>>,指示C#根據提供的lambda表達式構建表達式樹。

然後,這樣的事情應該工作:

private void WriteColumns(HttpResponseBase response) 
{ 
    var columnNames = columns 
     .Select(lambda => { 
      var expressionBody = lambda.Body; 
      var memberExpression = (MemberExpression)expressionBody; 
      var memberName = memberExpression.Member.Name; 
      return memberName; 
     }) 
     .ToList(); 
    foreach (var column in Columns) 
     WriteCsvCell(response, column.ToString()); 

    response.Write(Environment.NewLine); 
} 
相關問題