Papa.Coen
Papa.Coen

Reputation: 91

MVC Custom Model attribute to HTML attribute

I'm currently misusing (for as far as I know) a ValidateAttribute to get a model attribute displayed when generating a HTML view.

I have a model property, with a custom attribute (enabling some clientside Json handling):

[JsonResultPair("Zipcode","City")]
public virtual string City { get; set; }

Which is used in the view like this:

@Html.TextBoxFor(m => m.City, new { @class = "A", tabindex = 10, title = "B" })

Which results in:

<input class="A" data-val="true" data-val-pair="" data-val-pair-fld="City" data-val-pair-src="Zipcode" id="City" name="City" tabindex="10" title="B" type="text" value=""/>

But ideally, I want to leave out the data-val-pair="" attribute, normally used for holding error messages, because this isn't an actual validation. And I'd like to use data-value (or whatever custom name after data-) instead of data-val. Any ideas on how to do this?

My current attribute implementation:

[AttributeUsage(AttributeTargets.Property)]
public class JsonResultPair: ValidationAttribute
{
    private readonly String _source;
    private readonly String _field;

    public JsonResultPair(String source, String field)
    {
        _source = source;
        _field = field;
    }

    public String Source { get { return _source; } }
    public String Field { get { return _field; } }
}

My current adapter implementation:

// thanks: http://stackoverflow.com/questions/4120792/how-can-i-have-a-custom-validationattribute-rendered-as-a-data-val-xx-attribut
public class JsonResultPairAdapter : DataAnnotationsModelValidator<JsonResultPair>
{
    private const String Pair = "pair";
    private const String PairSource = "src";
    private const String PairField = "fld";

    public JsonResultPairAdapter(ModelMetadata metadata, ControllerContext context, JsonResultPair attribute) : base(metadata, context, attribute)
    {
    }

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
    {
        ModelClientValidationRule rule = new ModelClientValidationRule
        {
            ErrorMessage = ErrorMessage,
            ValidationType = Pair
        };

        rule.ValidationParameters.Add(PairSource, Attribute.Source);
        rule.ValidationParameters.Add(PairField, Attribute.Field);

        return new []{ rule};
    }
}

Upvotes: 1

Views: 2797

Answers (1)

YavgenyP
YavgenyP

Reputation: 2123

I think this blog contains a very good / detailed answer for your question: add html attributes

The basics steps are:

  1. create a custom attribute (which you've already done), don't inherit from the validation attributes
  2. create a metadata provider, based on the data annotation provider, which will also read / add your attributes to the model's metadata
  3. either create a template for the Textbox, or within the view itself query Model.Metadata, to get the custom attribute and its value you are using.

Upvotes: 1

Related Questions