2010-12-28 6 views
2

So, ich habe ein Kontaktformular in meiner MVC 2-Anwendung.Rufen Sie das Attribut DisplayName aus der Eigenschaft eines MVC2-Modells ab

Ich möchte alle Eigenschaften meines "ContactModel" programmatisch per E-Mail senden.

Hier ist, was ich möchte in psuedo-ish Code tun:

[HttpPost] 
public ActionResult Contact(ContactModel model) 
    if(!ModelState.IsValid){ 
     TempData["errorMessage"] = "You are a failure!"; 
     return View(model); 
    } 
    else{ 
     var htmlMessage = new StringBuilder("<table>"); 
     const string templateRow = "<tr><td>{0}: </td><td><strong>{1}</strong></td></tr>"; 

     /* ************************************************* */ 
     /* This is the part I need some serious help with... */ 
     /* ************************************************* */ 
     foreach(var property in someEnumerableObjectBasedOnMyModel){ 
      htmlMessage.AppendFormat(templateRow, 
       // the display name for the property 
       property.GetDisplayName(), 
       // the value the user input for the property (HTMLEncoded) 
       model[property.Key] 
      ); 
     } 
     /* ************************************************* */ 

     htmlMessage.Append("</table>"); 

     // send the message... 
     SomeMagicalEmailer.Send("[email protected]", "[email protected]", "Subject of Message ", htmlMessage.ToString()); 
     TempData["message"] = "You are awesome!"; 
     return RedirectToAction("Contact", "Home"); 
    } 
} 

Falls es darauf ankommt ... ContactModel richtet die DisplayName Attribute wie folgt aus:

[DisplayName("First Name")] 
public string FirstName {get; set ;} 

Ich möchte dies schön und trocken halten, indem ich die DisplayName-Namen nicht wiederhole.

Insbesondere möchte ich über jede Eigenschaft in meinem ContactModel auflisten, seinen DisplayName abrufen und seinen übermittelten Wert abrufen.

Antwort

3

Sie müssen Reflektion über die Objekteigenschaften und ihre benutzerdefinierten Attribute verwenden, um ihre Name/Wert-Paare zu erhalten.

foreach (var property in typeof(ContactModel).GetProperties()) 
{ 
    var attribute = property.GetCustomAttributes(typeof(DisplayNameAttribute),false) 
          .Cast<DisplayNameAttribute>() 
          .FirstOrDefault(); 
    if (attribute != null) 
    { 
      var value = property.GetValue(model, null); 
      var name = attribute.DisplayName; 

      htmlMessage.AppendFormat(templateRow, name, value); 
    } 
} 
+0

+1 Das funktioniert super. Gibt es einen Weg, es ohne Reflexion zu tun? Die App wird unter MediumTrust ausgeführt. : -/ –

+0

@David - die Attribute nicht direkt verwenden. – tvanfosson

+2

für Passanten: Sie können den DisplayName über: 'ModelMetadata.FromLambdaExpression (Ausdruck, neues ViewDataDictionary (Modell)) .DisplayName;' –

Verwandte Themen