MVC 5.1 and higher solution (will merge local HtmlAttributes and defined in the EditorTemplates):
Shared\EditorTemplates\String.cshtml:
@Html.TextBoxFor(model => model, new { @class = "form-control", placeholder = ViewData.ModelMetadata.Watermark }.ToExpando().MergeHtmlAttributes(ViewData["htmlAttributes"].ToExpando()))
Extensions:
public static IDictionary MergeHtmlAttributes(this ExpandoObject source1, dynamic source2)
{
Condition.Requires(source1, "source1").IsNotNull().IsLongerThan(0);
IDictionary result = source2 == null
? new Dictionary()
: (IDictionary) source2;
var dictionary1 = (IDictionary) source1;
string[] commonKeys = result.Keys.Where(dictionary1.ContainsKey).ToArray();
foreach (var key in commonKeys)
{
result[key] = string.Format("{0} {1}", dictionary1[key], result[key]);
}
foreach (var item in dictionary1.Where(pair => !result.ContainsKey(pair.Key)))
{
result.Add(item);
}
return result;
}
public static ExpandoObject ToExpando(this object anonymousObject)
{
IDictionary anonymousDictionary = new RouteValueDictionary(anonymousObject);
IDictionary expando = new ExpandoObject();
foreach (var item in anonymousDictionary)
expando.Add(item);
return (ExpandoObject)expando;
}
public static bool HasProperty(this ExpandoObject expando, string key)
{
return ((IDictionary)expando).ContainsKey(key);
}
Usage:
@Html.EditorFor(m => m.PromotionalCode, new { htmlAttributes = new { ng_model = "roomCtrl.searchRoomModel().promoCode" }})