Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing attributes from Custom Html Helpers in asp.net mvc 4 razor

Tags:

I have created HtmlHelper in ASP.NET MVC 4 razor view engine C#.
Can I pass view model property to my helper class?
For example, I have property

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

Can I pass this property to my helper something like this @Html.Example(model => model.Lastname) and then get data annotations in helper (if this field is required what is display name and etc.)?

like image 232
Irakli Lekishvili Avatar asked Jun 10 '12 16:06

Irakli Lekishvili


1 Answers

The [Display] attribute enriches the metadata. So you could fetch the information from the metadata.

For example if you wanted to retrieve the display name inside the helper:

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));     } } 

and then if we assume that you have a view model:

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

you could use the helper in your strongly typed view:

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

Now let's suppose that you wrote a custom metadata attribute:

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;     } } 

that you used to decorate your model with:

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

and then inside your helper you could fetch the custom attribute:

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:

It seems that you need to fetch the Required message. No idea why you need to do this in a custom helper but here's an example how you could achieve that:

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;     } } 
like image 79
Darin Dimitrov Avatar answered Oct 26 '22 21:10

Darin Dimitrov