ASP.NET MVC 3 - Data Annoation and Max Length/Size for Textbox Rendering

感情迁移 提交于 2019-12-03 06:46:10

Here is a 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);
}

Does this not work?

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

In the View:

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

or:

@Html.EditorFor(x => x.UserName)

I find that I prefer my views to just Call Html.EditorFor(...). This means that the Editor and Display templates decide the fate of controls in my view, such that my view code gets cleaned up a lot - it just has html and generic requests for editors.

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

I'm using similar in my String.cshtml Editor Template (goes in 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 such as:

[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 simply 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 might also notice that my String.cshtml Editor Template also auto-magically handles Enum's, but that is starting to digress from the current topic, so I nixed that code, I'll just say here that the String Editor Template can pull extra weight, and likely google has someting on that https://www.google.com/search?q=string+editor+template+enum

Label With Tooltip For is a custom HTML helper that just drops the description into the label title, for more information on mouse over for every label.

I'd recommend this approach if you want to do this in an Editor Template.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!