Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

maxlength attribute of a text box from the DataAnnotations StringLength in Asp.Net MVC

I am working on an MVC2 application and want to set the maxlength attributes of the text inputs.

I have already defined the stringlength attribute on the Model object using data annotations and it is validating the length of entered strings correctly.

I do not want to repeat the same setting in my views by setting the max length attribute manually when the model already has the information. Is there any way to do this?

Code snippets below:

From the Model:

[Required, StringLength(50)]
public string Address1 { get; set; }

From the View:

<%= Html.LabelFor(model => model.Address1) %>
<%= Html.TextBoxFor(model => model.Address1, new { @class = "text long" })%>
<%= Html.ValidationMessageFor(model => model.Address1) %>

What I want to avoid doing is:

<%= Html.TextBoxFor(model => model.Address1, new { @class = "text long", maxlength="50" })%>

I want to get this output:

<input type="text" name="Address1" maxlength="50" class="text long"/>

Is there any way to do this?

like image 909
Pervez Choudhury Avatar asked Mar 05 '10 11:03

Pervez Choudhury


People also ask

How do I set the MaxLength for HTML TextBoxFor in MVC?

The TextBox for the Name value is created using Html. TextBoxFor function while the TextBox for the Mobile Number value is created using Html. TextBox helper function. The MaxLength of both the TextBoxes is set using the HTML MaxLength attribute using the HtmlAttributes parameter in Html.

What is DataAnnotations MVC?

DataAnnotations is used to configure your model classes, which will highlight the most commonly needed configurations. DataAnnotations are also understood by a number of . NET applications, such as ASP.NET MVC, which allows these applications to leverage the same annotations for client-side validations.

What is System ComponentModel DataAnnotations?

Data annotations (available as part of the System. ComponentModel. DataAnnotations namespace) are attributes that can be applied to classes or class members to specify the relationship between classes, describe how the data is to be displayed in the UI, and specify validation rules.


3 Answers

If you're using unobtrusive validation, you can handle this client side as well:

$(document).ready(function () {     $("input[data-val-length-max]").each(function ()     {         var $this = $(this);         var data = $this.data();         $this.attr("maxlength", data.valLengthMax);     }); }); 
like image 174
jrummell Avatar answered Nov 16 '22 01:11

jrummell


I am not aware of any way to achieve this without resorting to reflection. You could write a helper method:

public static MvcHtmlString CustomTextBoxFor<TModel, TProperty>(
    this HtmlHelper<TModel> htmlHelper, 
    Expression<Func<TModel, TProperty>> expression, 
    object htmlAttributes
)
{
    var member = expression.Body as MemberExpression;
    var stringLength = member.Member
        .GetCustomAttributes(typeof(StringLengthAttribute), false)
        .FirstOrDefault() as StringLengthAttribute;

    var attributes = (IDictionary<string, object>)new RouteValueDictionary(htmlAttributes);
    if (stringLength != null)
    {
        attributes.Add("maxlength", stringLength.MaximumLength);
    }
    return htmlHelper.TextBoxFor(expression, attributes);
}

which you could use like this:

<%= Html.CustomTextBoxFor(model => model.Address1, new { @class = "text long" })%>
like image 21
Darin Dimitrov Avatar answered Nov 15 '22 23:11

Darin Dimitrov


I use the CustomModelMetaDataProvider to achieve this

Step 1. Add New CustomModelMetadataProvider class

public class CustomModelMetadataProvider : DataAnnotationsModelMetadataProvider
{   
    protected override ModelMetadata CreateMetadata(
        IEnumerable<Attribute> attributes,
        Type containerType,
        Func<object> modelAccessor,
        Type modelType,
        string propertyName)
    {
        ModelMetadata metadata = base.CreateMetadata(attributes,
            containerType,
            modelAccessor,
            modelType,
            propertyName);

        //Add MaximumLength to metadata.AdditionalValues collection
        var stringLengthAttribute = attributes.OfType<StringLengthAttribute>().FirstOrDefault();
        if (stringLengthAttribute != null)
            metadata.AdditionalValues.Add("MaxLength", stringLengthAttribute.MaximumLength);

        return metadata;
    }
}

Step 2. In Global.asax Register the CustomModelMetadataProvider

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    RegisterRoutes(RouteTable.Routes);
    ModelMetadataProviders.Current = new CustomModelMetadataProvider();
}

Step 3. In Views/Shared/EditorTemplates Add a partial view called String.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%if (!ViewData.ModelMetadata.AdditionalValues.ContainsKey("MaxLength")) { %>
    <%: Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue,  new { @class = "text-box single-line" }) %>
<% } else {
    int maxLength = (int)ViewData.ModelMetadata.AdditionalValues["MaxLength"];
    %>
    <%: Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { @class = "text-box single-line", MaxLength = maxLength  })%>
<% } %>

Done...

Edit. The Step 3 can start to get ugly if you want to add more stuff to the textbox. If this is your case you can do the following:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%
    IDictionary<string, object> Attributes = new Dictionary<string, object>();
    if (ViewData.ModelMetadata.AdditionalValues.ContainsKey("MaxLength")) {
        Attributes.Add("MaxLength", (int)ViewData.ModelMetadata.AdditionalValues["MaxLength"]);
    }
    if (ViewData.ContainsKey("style")) {
        Attributes.Add("style", (string)ViewData["style"]);
    }
    if (ViewData.ContainsKey("title")) {
        Attributes.Add("title", (string)ViewData["title"]);
    }
%>
<%: Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, Attributes)%>
like image 43
Randhir Avatar answered Nov 16 '22 00:11

Randhir