Jason Foglia
Jason Foglia

Reputation: 2531

Custom HTML attributes in MVC3 Model

I want to create a Model:

public class TestModel
{
    Microdata(Data = "data-test=this is a test!")]
    public bool Test { get; set; }
}

Then in the view:

@Html.DisplayForModel()

The result i'm looking for is something like this:

<label>Test:</label> <input type="checkbox" data-test="this is a test!" />

I've already created a custom attribute class, but this didn't produce anything.

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class MicrodataAttribute : Attribute
{
    public string Data { get; set; }

    public RouteValueDictionary GetAttributes()
    {
        var attributes = new RouteValueDictionary();

        if (this.Data != null)
        {
            string[] kv = this.Data.Split(',');
            attributes.Add(kv[0], kv[1]);
        }
        return attributes;
    }
}



public class MetadataProvider : DataAnnotationsModelMetadataProvider
{
    protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
    {
        var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
        var additionalValues = attributes.OfType<HtmlPropertiesAttribute>().FirstOrDefault();
        if (additionalValues != null)
        {
            metadata.AdditionalValues.Add("HtmlAttributes", additionalValues);
        }
        return metadata;
    }
}

Upvotes: 1

Views: 2381

Answers (2)

Jason Foglia
Jason Foglia

Reputation: 2531

After discussing the issue with @JakubKonecki and reading the blog post he presented. Here is my EditTemplate used to help create data dash attributes in MVC 2/3 and most likely 4.

I saved this file under root/Views/Shared/EditTemplates as String.cshtml. cshtml since i'm using the razor engine. The location can be different if you are using Area's and they don't have to be stored in "Shared" views folder. Just read the entire blog @JakubKonecki posted by Brad Wilson.

Thanks again @JakubKonecki!

@{
    Dictionary<string, object> AV = ViewData.ModelMetadata.AdditionalValues;
    Dictionary<string, object> htmlAttr = new Dictionary<string,object>();
    foreach (KeyValuePair<string, object> A in AV)
    {
        if (A.Value is System.Web.Routing.RouteValueDictionary)
        {
            foreach (KeyValuePair<string, object> B in (System.Web.Routing.RouteValueDictionary)A.Value)
            {
                htmlAttr.Add(B.Key, B.Value);
            }
        }
    }
    htmlAttr.Add("class", "text-box single-line");
    htmlAttr.Add("type", "text");
}

@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, htmlAttr)

Upvotes: 0

Jakub Konecki
Jakub Konecki

Reputation: 46008

Why would it? There's no code that uses your attribute...

Read the blog post below - it describes how MVC uses metadata and has an example of a custom object template you will need to write:

http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-1-introduction.html

Upvotes: 2

Related Questions