Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CustomAttribute reflects html attribute MVC5

Hoping to find a way when in MVC5 a Custom attribute or preferable the RegularExpressionAttribute decorates a property in the model the html control will contain it as another attribute of the control. E.g.

class CoolModel {
   [CustomHtmlAttribute("hello")]
   public string CoolValue {get;set;} 
}

outputs...

<input type="text" customhtml="hello" />

Or something like that. So for the RegularExpressionAttribute the pattern attribute will be awesome.

class CoolModel {
   [RegularExpressionAttribute("/d")]
   public string CoolValue {get;set;} 
}

outputs...

<input type="text" pattern="/d" />

I need this output without enabling the Javascript unobtrusive option. So I'm thinking in a way to specify some attribute in the model that gets push down to the view. Not sure if the Data annotations provider could do this job. Not sure if a Helper could be extended to get this result.

Help is appreciated.

like image 977
user1791567 Avatar asked Apr 12 '26 21:04

user1791567


1 Answers

If using the standard helpers with the overload to add html attributes is not acceptable, then you can create an attribute implements IMetadataAware that adds properties to metadata.AdditionalValues which can then be used in custom html helpers. A simple example might be

[AttributeUsage(AttributeTargets.Property)]
public class CustomHtmlAttribute : Attribute, IMetadataAware
{
  public static string ValueKey
  {
    get { return "Value"; }
  }
  public string Value { get; set; }
  public void OnMetadataCreated(ModelMetadata metadata)
  {
    if (Value != null)
    {
      metadata.AdditionalValues[ValueKey] = Value;
    }
  }
}

and to create a helper to render a textbox (only one overload shown here)

public static MvcHtmlString CustomHtmlTextBoxFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression)
{
  ModelMetadata metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
  object attributes = null;
  if (metaData.AdditionalValues.ContainsKey(ValueKey))
  {
    attributes = new { customhtml = (string)metaData.AdditionalValues[ValueKey] };
  }
  return InputExtensions.TextBoxFor(helper, expression, attributes);
}

and use it as

[CustomHtml(Value = "hello")]
public string CoolValue { get; set; } 

and in the view

@Html.CustomHtmlTextBoxFor(m => m.CoolValue)

to make this a bit more flexible, you could add more properties to the attribute so you could apply it as

[CustomHtml(Value = "hello", Pattern="/d")]
public string CoolValue { get; set; }

and modify the helper to render all the html attributes you define.