2012-06-10 4 views
23

Ich habe HtmlHelper in asp.net mvc 4-Rasierer-Ansicht-Engine C# erstellt.Zugriff auf Attribute von benutzerdefinierten HTML-Helfern in asp.net mvc 4 Rasiermesser

Kann ich die View-Modelleigenschaft an meine Hilfsklasse übergeben?

Zum Beispiel, ich habe Eigenschaft

[Required] 
[Display(Name = "Your Lastname")] 
public string Lastname { get; set; } 

Kann ich diese eigenschaft auf meine Helfer so etwas wie dieses @ Html.Example passieren (Modell => model.Lastname) und als Daten anotations in Helfer (wenn diese Feld ist erforderlich, was ist der Anzeigename und etc.)?

Dank

Antwort

38

Das [Display] Attribut bereichert die Metadaten. So könnten Sie die Informationen aus den Metadaten abrufen.

Zum Beispiel, wenn Sie die Anzeigenamen in dem Helfer abrufen wollten:

public static class HtmlHelpers 
{ 
    public static IHtmlString Example<TModel, TProperty>(
     this HtmlHelper<TModel> html, 
     Expression<Func<TModel, TProperty>> ex 
    ) 
    { 
     var metadata = ModelMetadata.FromLambdaExpression(ex, html.ViewData); 
     var displayName = metadata.DisplayName; 
     return new HtmlString(html.Encode(displayName)); 
    } 
} 

und dann, wenn wir annehmen, dass Sie einen Blick Modell: in

public class MyViewModel 
{ 
    [Required] 
    [Display(Name = "Your Lastname")] 
    public string Lastname { get; set; } 
} 

die Helfer verwenden könntest Ihre stark typisierte Ansicht:

@model MyViewModel 

@Html.Example(x => x.Lastname) 

Nehmen wir jetzt an, dass Sie eine benutzerdefinierte Metadaten an geschrieben haben Tribut:

public class FooBarAttribute : Attribute, IMetadataAware 
{ 
    public FooBarAttribute(string bar) 
    { 
     Bar = bar; 
    } 
    public string Bar { get; private set; } 

    public void OnMetadataCreated(ModelMetadata metadata) 
    { 
     metadata.AdditionalValues["foo"] = Bar; 
    } 
} 

, mit dem Sie Ihr Modell dekorieren mit:

public class MyViewModel 
{ 
    [Required] 
    [FooBar("This is the bar")] 
    public string SomeBar { get; set; } 
} 

und dann in Ihrem Helfer könnten Sie das benutzerdefinierte Attribut holen:

public static class HtmlHelpers 
{ 
    public static IHtmlString Example<TModel, TProperty>(
     this HtmlHelper<TModel> html, 
     Expression<Func<TModel, TProperty>> ex 
    ) 
    { 
     var metadata = ModelMetadata.FromLambdaExpression(ex, html.ViewData); 
     if (metadata.AdditionalValues.ContainsKey("foo")) 
     { 
      var foo = metadata.AdditionalValues["foo"] as string; 
      return new HtmlString(html.Encode(foo)); 
     } 
     return MvcHtmlString.Empty; 
    } 
} 

UPDATE:

Es scheint, dass Sie n um die erforderliche Nachricht abzurufen. Keine Ahnung, warum Sie dies in einem benutzerdefinierten Helfer tun müssen, aber hier ist ein Beispiel, wie Sie das erreichen konnten:

public static class HtmlHelpers 
{ 
    public static IHtmlString Example<TModel, TProperty>(
     this HtmlHelper<TModel> html, 
     Expression<Func<TModel, TProperty>> ex 
    ) 
    { 
     var me = (ex.Body as MemberExpression); 
     if (me != null) 
     { 
      var required = me 
       .Member 
       .GetCustomAttributes(typeof(RequiredAttribute), false) 
       .Cast<RequiredAttribute>() 
       .FirstOrDefault(); 
      if (required != null) 
      { 
       var msg = required.FormatErrorMessage(me.Member.Name); 
       return new HtmlString(html.Encode(msg)); 
      } 
     } 
     return MvcHtmlString.Empty; 
    } 
} 
+2

Wow. Ich denke, du bist toll :) Danke, –

+0

und können Sie sagen, wie ich Daten-val-erforderliche Nachricht finden kann? Ich möchte diese Nachricht erhalten >>> data-val-date = "Das Feld BirthDate muss ein Datum sein." data-val-required = "Das Feld" BirthDate "ist erforderlich. –

+0

" data-val-required "ist ein clientseitiges Attribut. Ich nehme an, Sie möchten die Nachricht abrufen, die vom Required-Attribut verwendet wird. Ich werde meine Antwort mit einem aktualisieren Beispiel: –