ASP.NET MVC 3 - 数据处理和文本框渲染的最大长度/大小

时间:2011-08-29 14:24:55

标签: asp.net-mvc-3 data-annotations razor

我知道在Razor View文件中,我们可以做这样的事情 @ Html.TextBox(“username”,null,new {maxlength = 20,autocomplete =“off”})

但是,我希望为MVC创建一个模型,该模型可用于创建一个明确定义文本框大小和最大长度的表单。我在模型的属性上尝试[StringLength(n)],但这似乎只进行验证而不是设置文本框的大小。

无论如何,我们可以将文本字段的长度定义为模型属性顶部的数据注释吗?

最终,我们可以通过使用razor映射到模型来创建整个表单,而不是逐个明确地获取模型属性以设置文本框大小。

3 个答案:

答案 0 :(得分:14)

以下是使用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);
}

答案 1 :(得分:3)

这不起作用吗?

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

在视图中:

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

或:

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

答案 2 :(得分:2)

我发现我更喜欢我的观点只是调用 Html.EditorFor(...)。这意味着编辑器和显示模板在我的视图中决定控件的命运,这样我的视图代码就会被清理很多 - 它只是对编辑器有html和泛型请求。

以下链接提供了使用编辑模板进行此操作的工作示例 https://jefferytay.wordpress.com/2011/12/20/asp-net-mvc-string-editor-template-which-handles-the-stringlength-attribute/

我在 String.cshtml 编辑器模板中使用了类似的内容(进入 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...

然后我的模型会被注释,例如:

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

我的查看只是致电:

<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>

您可能还会注意到我的String.cshtml编辑器模板也会自动神奇地处理Enum,但这已经开始偏离当前主题了,所以我添加了该代码,我只是在这里说字符串编辑器模板可以增加额外的权重,并且可能谷歌有点https://www.google.com/search?q=string+editor+template+enum

标签与工具提示For是一个自定义HTML帮助器,只是将描述删除到标签标题,有关每个标签的鼠标悬停的更多信息。

如果您想在编辑模板中执行此操作,我建议使用此方法。