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.)?
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; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With