2016-01-07 31 views
0

這是另一篇文章的延續。我正在嘗試創建一個接口,使我能夠瀏覽一組對象,並訪問該對象的屬性名稱。如何獲取我的ReportItems的類型

A Report對象將有ReportSections。 A ReportSection將有一個ICollection項目將根據使用情況而改變。

下面是我現在想要定義它的方法。

public interface IReport 
{ 
    string ReportName { get; set; } 

    ICollection<IReportSection> ReportSections { get; } 
} 

public interface IReportSection 
{ 
    string ReportSectionName { get; set; } 

    ICollection ReportItems { get; } 
} 

public abstract class ReportBase : IReport 
{ 
    virtual public string ReportType { get; set; } 

    virtual public string ReportName { get; set; } 

    virtual public ICollection<IReportSection> ReportSections { get; set; } 

} 

public abstract class ReportSectionBase : IReportSection 
{ 
    public string ReportSectionName { get; set; } 

    public ICollection ReportItems { get; set; } 
} 

在我的代碼,我這樣做:

public class BookAffiliates : ReportSectionBase 
{ 
    public override string ReportSectionName { get { return "Book Affiliates"; } } 

    public override ICollection ReportItems { get; set; } 
} 

public class SomeClass 
{ 
    public ICollection<AuthorsViewModel> Authors { get; set; } 

    public ICollection<ProjectSubmissionViewModel> Submissions { get; set; } 

    public string ProcessAuthorsReport() 
    { 
     var report = new ContribAuthorsReport{ ReportType = "CSV" }; 

     var authorAffil = new BookAffiliates {ReportItems = Authors }; 
     report.ReportSections.Add(chapAffil); 

     var submissionAffil = new BookAffiliates {ReportItems = Submissions}; 
     report.ReportSections.Add(submissionAffil); 

     return RenderReport(report) 
    } 

} 

RenderReport我想通過收藏走路和使用PropertyNames:

private string RenderReport(ReportBase currentReport) 
{ 
    var reportBody = new StringBuilder(); 
    reportBody.Append(currentReport.ReportName + Environment.NewLine + Environment.NewLine); 

    foreach (var thisSection in currentReport.ReportSections) 
    { 
     reportBody.Append(thisSection.ReportSectionName + Environment.NewLine); 

     /// ---- Here! Here! I don't know what type, I want the 
     /// code to get the type based on ReportSectionBase<T> 
     var firstItem = thisSection.ReportItems.OfType<???Type???>().FirstOrDefault(); 

     // I would actually like to go through each property of 
     // the ReportItem type and list it here. 
     foreach(var prop in firstItem.GetType().GetProperties()) 
     { 
       reportBody.AppendLine(string.Format("{0}:{1}" prop.Name, prop.Value)); 
     } 
    } 

    return reportBody.ToString(); 
} 

我不知道如何最好地定義這一點。我很確定我以前做過這件事,但這不是我想要的。

+0

[如何獲得某個類的屬性列表?](http://stackoverflow.com/questions/737151/how-to-get-the-list-of-properties-of-a-類) – stuartd

+0

請不要重複。我添加了更多評論。 –

+0

'T'是什麼類? – stuartd

回答

0

您將使用反射來做到這一點。

foreach(var prop in thisItem.GetType().GetProperties()) 
{ 
     reportBody.AppendLine(string.Format("{0}:{1}" prop.Name, prop.Value)); 
} 
+0

是否可以獲取DataAnnotation值? –

+0

你是指屬性名稱和值? – Marshal

+0

是的,例如'[Display(Name =「Revision Due Date」)]' –

0

花了一段時間,很多問題,並搞清楚我真正想問什麼。我想出了這個。

這裏是我的接口和基類:

public class ReportBase 
{ 
    public ReportBase() 
    { 
     ReportSections = new List<IReportSection>(); 
    } 

    public string ReportType { get; set; } 

    public string ReportName { get; set; } 

    public ICollection<IReportSection> ReportSections { get; set; } 

} 
public interface IReportSection 
{ 
    string ReportSectionName { get; } 

    ICollection ReportItems { get; set; } 
} 

public class ReportSection<T> : IReportSection 
{ 
    public string ReportSectionName { get; set; } 

    public ICollection<T> ReportItems { get; set; } 

    ICollection IReportSection.ReportItems 
    { 
     get { return ReportItems as ICollection; } 
     set { ReportItems = value as ICollection<T>; } 
    } 
} 

創建我的對象是這樣的:

public ReportBase GetContribAuthorsReport 
(
    ICollection<ProjectAffiliateViewModel> projectAffiliates, 
    ICollection<SubmissionAffiliateViewModel> submissionAffiliates 
) 
{ 
    //var caReport = new ContributingAffiliates("CSV", projectAffiliates, submissionAffiliates); 
    var caReport = new ReportBase { ReportType = "CSV", ReportName = "Reviewers' Contact Information" }; 

    caReport.ReportSections.Add(new ReportSection<ProjectAffiliateViewModel> { ReportItems = projectAffiliates }); 
    caReport.ReportSections.Add(new ReportSection<SubmissionAffiliateViewModel> { ReportItems = submissionAffiliates }); 

    return caReport;//.Report; 
} 

然後,我通過對象重複這樣的:

public class DownloadCsvActionResult : ActionResult 
{ 
    public ReportBase Report { get; set; } 
    public string fileName { get; set; } 

    private string ReportData { get; set; } 

    public DownloadCsvActionResult(ReportBase report, string pFileName) 
    { 
     Report = report; 
     fileName = pFileName; 
     ReportData = RenderReport(); 
    } 

    private string RenderReport() 
    { 
     var reportBody = new StringBuilder(); 

     reportBody.AppendLine(Report.ReportName); 
     reportBody.Append(Environment.NewLine + Environment.NewLine); 

     foreach (var thisSection in Report.ReportSections) 
     { 
      reportBody.Append(thisSection.ReportSectionName + Environment.NewLine); 

      if (thisSection.ReportItems != null) 
      { 
       var itemType = thisSection.ReportItems.GetType().GetGenericArguments().Single(); 

       var first = true; 
       foreach (var prop in itemType.GetProperties()) 
       { 
        if (!first) reportBody.Append(","); 

        DisplayAttribute attribute = prop.GetCustomAttributes(typeof(DisplayAttribute), false) 
         .Cast<DisplayAttribute>() 
         .SingleOrDefault(); 

        string displayName = (attribute != null) ? attribute.Name : prop.Name; 
        reportBody.Append(displayName); 

        first = false; 
       } 
       reportBody.Append(Environment.NewLine); 

       foreach (var thisItem in thisSection.ReportItems) 
       { 
        var firstData = true; 
        foreach (var prop in itemType.GetProperties()) 
        { 
         if (!firstData) reportBody.Append(","); 
         reportBody.Append(prop.GetValue(thisItem,null)); 
         firstData = false; 
        } 
        reportBody.Append(Environment.NewLine); 
       } 
      } 

      reportBody.Append(Environment.NewLine); 
     } 

     return reportBody.ToString(); 
    } 

    public override void ExecuteResult(ControllerContext context) 
    { 
     //Create a response stream to create and write the Excel file 
     HttpContext curContext = HttpContext.Current; 
     curContext.Response.Clear(); 
     curContext.Response.AddHeader("content-disposition", "attachment;filename=" + fileName); 
     curContext.Response.Charset = ""; 
     curContext.Response.Cache.SetCacheability(HttpCacheability.NoCache); 
     curContext.Response.ContentType = "application/vnd.ms-excel"; 

     //Write the stream back to the response 
     curContext.Response.Write(ReportData); 
     curContext.Response.End(); 

    } 
} 

這給了我現在需要的東西。對不起,我首先不太清楚,並感謝你的幫助。