ASP.NET MVC 3 - data annotation and maximum length / size for rendering a text field

I know in the Razor View file, we can do something like this @ Html.TextBox ("username", null, new {maxlength = 20, autocomplete = "off"})

However, I hope to create a model for MVC that can be used to create a form with a clearly defined size and maximum length of text fields. I am trying to use [StringLength (n)] on top of the model properties, but it seems to only do the validation, not set the size of the text field.

In any case, can we define the length of the text field as an annotation of the data on top of the model property?

Thus, in the end, we could just create the whole form using a razor to match the model, and not to explicitly select the model properties one by one to set the size of the text box.

+8
asp.net-mvc-3 razor data-annotations
source share
3 answers

Here is the outline of a custom helper that uses StringLengthAttribute .

 public class MyModel { [StringLength(50)] public string Name{get; set;} } public MvcHtmlString MyTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression) { var attributes = new Dictionary<string, Object>(); var memberAccessExpression = (MemberExpression)expression.Body; var stringLengthAttribs = memberAccessExpression.Member.GetCustomAttributes( typeof(System.ComponentModel.DataAnnotations.StringLengthAttribute), true); if (stringLengthAttribs.Length > 0) { var length = ((StringLengthAttribute)stringLengthAttribs[0]).MaximumLength; if (length > 0) { attributes.Add("size", length); attributes.Add("maxlength", length); } } return helper.TextBoxFor(expression, attributes); } 
+14
source share

Does this work?

 public class ViewModel { [StringLength(20)] public string UserName {get;set;} } 

In view:

 @Html.TextBoxFor(x => x.UserName, new {autocomplete = "off"}) 

or

 @Html.EditorFor(x => x.UserName) 
+3
source share

I believe that I prefer that my views simply call Html.EditorFor (...) . This means that the editor and display templates determine the fate of the controls in my opinion, so my view code is cleared very often - it just has html and general requests for editors.

The following link gives a working example of getting this work into the Editor Template https://jefferytay.wordpress.com/2011/12/20/asp-net-mvc-string-editor-template-which-handles-the-stringlength-attribute/

I use a similar one in my String.cshtml Editor Template (goes to Shared / EditorTemplates ).

 @model object @using System.ComponentModel.DataAnnotations @{ ModelMetadata meta = ViewData.ModelMetadata; Type tModel = meta.ContainerType.GetProperty(meta.PropertyName).PropertyType; } @if(typeof(string).IsAssignableFrom(tModel)) { var htmlOptions = new System.Collections.Generic.Dictionary<string, object>(); var stringLengthAttribute = (StringLengthAttributeAdapter)ViewData.ModelMetadata.GetValidators(this.ViewContext.Controller.ControllerContext).Where(v => v is StringLengthAttributeAdapter).FirstOrDefault(); if (stringLengthAttribute != null && stringLengthAttribute.GetClientValidationRules().First().ValidationParameters["max"] != null) { int maxLength = (int)stringLengthAttribute.GetClientValidationRules().First().ValidationParameters["max"]; htmlOptions.Add("maxlength", maxLength); if (maxLength < 20) { htmlOptions.Add("size", maxLength); } } htmlOptions.Add("class", "regular-field"); <text> @Html.TextBoxFor(m => m, htmlOptions) </text> } else if(typeof(Enum).IsAssignableFrom(tModel)) { //Show a Drop down for an enum using: //Enum.GetValues(tModel) //This is beyond this article } //Do other things for other types... 

Then my model is annotated, for example:

 [Display(Name = "Some Field", Description = "Description of Some Field")] [StringLength(maximumLength: 40, ErrorMessage = "{0} max length {1}.")] public string someField{ get; set; } 

And my View just calls:

 <div class="editor-label"> @Html.LabelWithTooltipFor(model => model.something.someField) </div> <div class="editor-field"> @Html.EditorFor(model => model.something.someField) @Html.ValidationMessageFor(model => model.something.someField) </div> 

You may also notice that my String.cshtml editor template also automatically controls Enum, but it starts to move away from the current section, so I used this code, I will just say here that the String template template can be overweight, and probably google has on it https://www.google.com/search?q=string+editor+template+enum

Label With Tooltip For is a special HTML helper that simply omits the description in the label name, for more information about the mouse for each label.

I would recommend this approach if you want to do this in an editor template.

+2
source share

All Articles