The first syntax is using an anonymous object, for which the same rules regarding how to create identifiers in C# apply:
- You can use any unicode character of the classes
Lu, Ll, Lt, Lm, Lo, or Nl
- You can scape C# keywords using "@" as in
new { @class = "foo" };
Since the colon belongs to the Po unicode class it cannot be used in an identifier. (In C# you can use the static method char.GetUnicodeCategory in order to check the class of any character)
Additionally, and only in MVC, when using an anonymous object for the html attributes in the helper, any attribute name with underscores will be replaced by hyphens. This is due to the method HtmlHelper.AnonymousObjectToHtmlAttributes
Back to your case and regarding your options, if those are not too widely used (like in a couple of views) I would consider staying with the Dictionary syntax of the TextBoxFor
helper. You will still get the automatic generation of the id\name properties in sync with the model binding, and you will get any other attributes from the model metadata like the unobtrusive validation attributes. (although looking at the attributes you want to preserve, it seems you won´t need the unobtrusive validation ones :) )
However if the id\name will be as simple as the name of the property and you don´t need any other html attributes that would be generated automatically using the helper, then going for the raw HTML makes sense. (as the dictionary syntax is quite ugly)
In case you use it widely across the application, then in my opinion the most sensible approach may be creating your own helper, like @Html.LegacyTextBoxFor(...)
. That helper will render those legacy attributes you want to kepp, and you can incorporate additionaly logic similar to the standard helpers for id\name attribute creation.
Something like this:
public class FooAttributes
{
public bool Required { get; set; }
public string Message { get; set; }
}
public static class FooHelper
{
public static MvcHtmlString LegacyTextboxFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, FooAttributes fooAttributes)
{
var fieldName = ExpressionHelper.GetExpressionText(expression);
var fullBindingName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(fieldName);
var fieldId = TagBuilder.CreateSanitizedId(fullBindingName);
var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
var value = metadata.Model;
TagBuilder tag = new TagBuilder("input");
tag.Attributes.Add("name", fullBindingName);
tag.Attributes.Add("id", fieldId);
tag.Attributes.Add("type", "text");
tag.Attributes.Add("value", value == null ? "" : value.ToString());
if (fooAttributes != null)
{
if (fooAttributes.Required) tag.Attributes.Add("foo:required", "true");
if (!String.IsNullOrEmpty(fooAttributes.Message)) tag.Attributes.Add("foo:message", fooAttributes.Message);
}
return new MvcHtmlString(tag.ToString(TagRenderMode.SelfClosing));
}
}
That can be used as:
@Html.LegacyTextboxFor(model => model.UserName, new FooAttributes {Required=true, Message="Please enter a value." })
And will generate this html:
<input foo:message="Please enter a value." foo:required="true" id="UserName" name="UserName" type="text" value="">
And once you have your own helper, you could add additionaly logic, for example logic that will generate those attributes from the model metadata and its data annotation attributes...
I have extended my answer more than intended, but I hope it helps!