2016-06-30 9 views
1

Mein Ziel ist es, MVC View Model in Excel zu exportieren. Ich möchte nur Spalten exportieren, für die das Attribut Anzeige festgelegt wurde.PropertyDescriptor vs PropertyInfo und Export nach Excel

I Eigenschaften erfolgreich gezogen Spaltennamen zu füllen:

 var type = typeof(MyViewModel); 
     var propertyMetaData = type.GetProperties() 
      .Select(property => property.GetCustomAttributes(typeof(DisplayAttribute), false).FirstOrDefault() as DisplayAttribute) 
      .Where(attribute => attribute != null) 
      .ToList(); 

     DataTable table = new DataTable(); 
     foreach (var prop in propertyMetaData) 
      table.Columns.Add(prop.Name); 

Mein Problem ist, wenn ich ma aufzufüllen Daten versuchen:

 PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(MyViewModel)); 
     foreach (MyViewModel item in lst_VM) 
     { 
      DataRow row = table.NewRow(); 

      foreach (PropertyDescriptor prop in properties) 
       if ((prop.GetType().GetCustomAttributes(typeof(DisplayAttribute), false).FirstOrDefault() as DisplayAttribute) != null) 
       { 
        row[prop.Name] = prop.GetValue(item) ?? DBNull.Value; 

        table.Rows.Add(row); 
       } 
     } 

Das Problem ist, dass der Code über alle Attribute Kommissionierung und Es wird der Fehler zurückgegeben, dass die Spalte nicht zur Tabelle gehört.

Meine Ansicht Modell sieht aus wie folgt:

[Display(Name = "Application Name")] 
    public string ApplicationName { get; set; } 
    [Required(ErrorMessage = "Make is required.")] 
    public int MakeID { get; set; } 
    [Display(Name = "Make")] 
    public string Make { get; set; } 

und ich will nur diese exportieren, die gesetzt haben [Display (Name = "")]

+1

'prop.GetType()' sieht wie ein Fehler aus; das wird Ihnen nur den konkreten Typ der Property-Deskriptor-Implementierung geben; meinst du "prop.PropertyType"? Hinweis: Die Verwendung von Reflektion an einer Stelle und 'PropertyDescriptor' in einer anderen: wird wahrscheinlich viele Probleme verursachen. Kannst du dich für das eine oder andere entscheiden? Sie können ** sehr ** anders sein. Auch: ist "[Display]" auf der Immobilie? oder auf dem * Typ * der Immobilie? Im Moment schlägt der Code den letzteren vor - aber die Konvention ist in der Regel erster. –

+0

Leider habe ich nur von Reflektion gehört. Ich würde es einfach funktionieren lassen. Ich werde schätzen, wenn Sie mir Lösung zur Verfügung stellen konnten. – ironcurtain

+0

Nun, es ist schwer zu erkennen, was Sie mit dem Code machen wollen. Aber von Ihrem "Mein Ansichtsmodell" sind die Attribute auf den Eigenschaften - Sie sollten also "prop.Attributes" betrachten (was eine Sammlung von Attributen ist). Sehen Sie, wenn es eine 'DisplayAttribute' -Instanz enthält -' prop.Attributes [typeof (DisplayAttribute)]! = Null' könnte das sein, was Sie wollen –

Antwort

0

Nach 10 Stunden des Suchens und versuche verschiedene Dinge, die ich schließlich gefunden habe, was ich brauche:

 foreach (MyViewModel item in lst_Host_VM) 
     { 
      DataRow row = table.NewRow(); 

      var test = typeof(MyViewModel).GetProperties() 
       .Where(p => p.IsDefined(typeof(DisplayAttribute), false)) 
       .Select(p => new 
       { 
        PropertyName = p.Name, 
        p.GetCustomAttributes(typeof(DisplayAttribute), false).Cast<DisplayAttribute>().Single().Name, 
        Value = p.GetValue(item) 
       }); 

      foreach (var itm in test) 
      { 
       row[itm.Name] = itm.Value; 
      } 

      table.Rows.Add(row); 
     } 

Wenn Sie denken, dass es tun könnte Bitte, lass mich es wissen.