Ahsan
Ahsan

Reputation: 2518

Custom Data Annotation and MVC Helper

I want to expose a globalized help text on to an MVC view.

Currently the code looks like this,

Custom attribute class

 class HelpTextAttribute : Attribute
 {
     public string Text { get; set; }
 }

View model property and custom annotation

[HelpText(Text = "This is the help text for member number")]
public string MemberNo { get; set; }

(The literal string must come from a resource class)

The question is how do i write an Html extension that could do the following

@Html.HelpTextFor(m => m.MemberNo)

Upvotes: 2

Views: 961

Answers (3)

Dominic
Dominic

Reputation: 1

About localizing the string (I cannot comment because I do not have enough points yet)

Add the following attributes to your HelpTextAttribute

 public string ResourceName { get; set; }
 public Type ResourceType { get; set; }

and then adjust the HelpTextFor as follows:

 var helpAttr = memberExpr.Member.GetCustomAttributes(false).OfType<HelpTextAttribute>().SingleOrDefault();

            Assembly resourceAssembly = helpAttr.ResourceType.Assembly;
            string[] manifests = resourceAssembly.GetManifestResourceNames();

            // remove .resources
            for (int i = 0; i < manifests.Length; i++)
            {
                manifests[i] = manifests[i].Replace(".resources", string.Empty);
            }

            string manifest = manifests.Where(m => m.EndsWith(helpAttr.ResourceType.FullName)).First();
            ResourceManager manager = new ResourceManager(manifest, resourceAssembly);

            if (helpAttr != null)
                return new MvcHtmlString(@"<span class=""help"">" + manager.GetString(helpAttr.ResourceName) + "</span>");

Please see the following link on why to remove .resources C# - Cannot getting a string from ResourceManager (from satellite assembly)

Best regards Dominic Rooijackers .NET software developer

Upvotes: 0

haim770
haim770

Reputation: 49095

You're gonna need to extend the HtmlHelper class with the following:

public static MvcHtmlString HelpTextFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expr)
{
    var memberExpr = expr.Body as MemberExpression;

    if (memberExpr != null)
    {
        var helpAttr = memberExpr.Member.GetCustomAttributes(false).OfType<HelpTextAttribute>().SingleOrDefault();

        if (helpAttr != null)
            return new MvcHtmlString(@"<span class=""help"">" + helpAttr.Text + "</span>");
    }

    return MvcHtmlString.Empty;
}

Then use it as requested:

@Html.HelpTextFor(m => m.MemberNo)

Also, be sure to mark your HelpTextAttribute with the public modifier.

Upvotes: 4

Phoenix_uy
Phoenix_uy

Reputation: 3294

Maybe you are doing things wrong because i think that DataAnnotations and MVC Helpers are different things.

i would do something like this: a helper view on my App_Code with the code:

@helper HelpTextFor(string text) {
     <span>@text</span>
}

and then use it as you wrote.

Upvotes: 0

Related Questions