Is there a way to modify the generated name attribute for TextboxFor, HiddenFor etc through ModelBinder?

838 views Asked by At

I've looked into this question and found questions such as:

SO-Link1 SO-Link2

So the problem seems rather common - but i really don't like the solution.

Question:

I've started digging into sources but couldn't find a convenient solution yet. Is there a built in solution to this by now using attributes?

Having to use dynamic parameters in place instead of using attributes on the model is very inconvenient.

Guess i'll see what i can achieve by modifying the ModelBinder in the meantime - there has to be some way i guess.

Update:

Why do i want to do this?

I want to reduce network traffic because properties in code may be long + nested. Imagine 200 Checkboxes x 40 bytes generated names.

I can already make my modelbinder work with aliases - however in order to fully automate it, i need the TextBoxFor etc methods to use alias names instead of the actual property names.

1

There are 1 answers

2
heymega On

Personally I don't think you should be totally concerned with the size of the the name attribute's values. As long as you're using compression through something like IIS then you aren't going to be saving that much.

You can however, achieve what you're after by creating custom HTML helpers which will create the HTML markup you desire.

Example Model

public class UserModel
{
    public string FullName { get; set; }
}

Helper

public static MvcHtmlString CustomTextBoxFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string name)
{
    var fieldName = ExpressionHelper.GetExpressionText(expression);

    //
    // Pass in alias or call method to get alias here
    //
    var fullBindingName = String.IsNullOrWhiteSpace(name) ? html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(fieldName) : name;
    var fieldId = TagBuilder.CreateSanitizedId(fullBindingName);

    var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
    var value = metadata.Model;

    var 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());

    var validationAttributes = html.GetUnobtrusiveValidationAttributes(fullBindingName, metadata);
    foreach (var key in validationAttributes.Keys)
    {
        tag.Attributes.Add(key, validationAttributes[key].ToString());
    }

    return new MvcHtmlString(tag.ToString(TagRenderMode.SelfClosing));
}

Call the Method in your View

   @Html.TextBoxFor(x => x.FullName)

   @Html.CustomTextBoxFor(x => x.FullName, "FName")

Output

<input id="FullName" type="text" value="Heymega" name="FullName">
<input id="FName" type="text" value="Heymega" name="FName">