Razor ViewModel中的StringLength未在文本框上设置maxlength
此处显示我的ViewModel中的属性:Razor ViewModel中的StringLength未在文本框上设置maxlength,razor,asp.net-mvc-4,Razor,Asp.net Mvc 4,此处显示我的ViewModel中的属性: [Display(Name = "Ext.")] [MaxLength(6, ErrorMessage = "Must be a maximum of 6 characters")] [StringLength(6)] public string Extension { get; set; } 在我看来: @Html.EditorFor(model => model.Extension) 它表明: <input class="text-b
[Display(Name = "Ext.")]
[MaxLength(6, ErrorMessage = "Must be a maximum of 6 characters")]
[StringLength(6)]
public string Extension { get; set; }
在我看来:
@Html.EditorFor(model => model.Extension)
它表明:
<input class="text-box single-line" data-val="true" data-val-length="The field Ext. must be a string with a maximum length of 6." data-val-length-max="6" id="Extension" name="Extension" type="text" value="" />
这是否应该在我的文本框上设置maxlength属性?如果没有,我如何使用DataAttributes实现这一点
我希望我在ViewModel中设置的属性能够控制这一点
可能
NET MVC提供了一个可扩展的系统来实现这一点。以下是您需要做的:
modelmataprovider
StringLengthAttribute
或MaxLengthAttribute
,提取信息并将其添加到ModelMetadata
modelmataprovider
创建从modelmataprovider
派生的类。通常,您可以从DataAnnotationsModelMetadataProvider
派生,因为这提供了一些默认功能,这意味着您只需重写名为CreateMatadata
的单个方法
步骤2:提取信息:
要获取信息,您需要查找属性,提取最大长度信息并将其添加到ModelMetadata
的AdditionalValues
字典中。实现类似于以下内容(这是整个实现):
步骤3:创建自定义编辑器模板
现在需要创建一个使用这些信息的视图。在Views\Shared\
文件夹中创建名为String
的新视图
String.cshtml
@{
object maxLength;
if (!ViewData.ModelMetadata.AdditionalValues
.TryGetValue("maxLength", out maxLength))
{
maxLength = 0;
}
var attributes = new RouteValueDictionary
{
{"class", "text-box single-line"},
{ "maxlength", (int)maxLength },
};
}
@Html.TextBox("", ViewContext.ViewData.TemplateInfo.FormattedModelValue, attributes)
运行应用程序时,通过调用@HTML.EditorFor
,您将获得以下HTML输出
<input class="text-box single-line" id="Extension" maxlength="6" name="Extension" type="text" value="" />
如果您想了解更多关于模型元数据提供程序系统的信息,请详细说明它的工作原理(这些是在Razor视图引擎之前编写的,因此一些视图语法有点古怪,但其他方面的信息是可靠的)。我遇到了类似的情况,下面是我快速而肮脏的解决方案: 在.cshtml文件的顶部添加以下行:
@{
var max = ((System.ComponentModel.DataAnnotations.StringLengthAttribute)(typeof(MyType))
.GetProperty("MyProp")
.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.StringLengthAttribute), true)[0]).MaximumLength;
}
在html的下面,将EditorFor替换为:
@Html.TextBoxFor(model => model.Extension, htmlAttributes: new {maxlength=max })
我最终决定我还是用剧本来写:
<script>
$(function ()
{
var max = $("#myinput").attr("data-val-length-max");
$("#myinput").attr("maxlength", max);
});
</script>
$(函数()
{
var max=$(“#myinput”).attr(“数据值长度max”);
$(“#myinput”).attr(“maxlength”,max);
});
但是,如果您不想添加脚本,第一个示例应该可以使用。基本上基于Brad的答案,在Html帮助程序上使用lambda语法包装了一个扩展,这样您就不会用反射内容污染Razor视图:
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Web.Mvc;
public static class HtmlHelper
{
public static int? MaxLength<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression)
{
MemberExpression memberExpression = (MemberExpression)expression.Body;
PropertyInfo property = typeof(TModel)
.GetProperty(memberExpression.Member.Name);
StringLengthAttribute attribute = (StringLengthAttribute)property
.GetCustomAttributes(typeof(StringLengthAttribute), true)
.FirstOrDefault();
if (attribute != null)
{
return attribute.MaximumLength;
}
return null;
}
}
其中x
指的是您的型号
如果未为属性声明StringLengthAttribute
,将返回null
,并且textbox元素的maxlength
属性将为空
请记住在razor页面中包含using,以便访问该方法
@using HtmlHelper
您还需要为该方法使用不允许为null的结果来克服编译错误。您是否验证了是否可以发布长度超过6个字符的字符串?我确实收到一个验证错误,但我希望它实际设置maxlength属性。如果您将其更改为
TextBoxFor
您可以传递HTML选项。是,但是如果可能的话,我希望我在ViewModel中设置的属性能够控制这一点。如果您使用非干扰性验证
,这可能会有帮助。Benjamin,您现在是一台机器!没问题,很高兴我能帮上忙。这段代码很有效,但您可能希望使用助手之类的工具保持Razor视图更清晰。请参见我的答案,以了解这方面的示例。
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Web.Mvc;
public static class HtmlHelper
{
public static int? MaxLength<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression)
{
MemberExpression memberExpression = (MemberExpression)expression.Body;
PropertyInfo property = typeof(TModel)
.GetProperty(memberExpression.Member.Name);
StringLengthAttribute attribute = (StringLengthAttribute)property
.GetCustomAttributes(typeof(StringLengthAttribute), true)
.FirstOrDefault();
if (attribute != null)
{
return attribute.MaximumLength;
}
return null;
}
}
@Html.TextBoxFor(x => x.Name, new { maxlength = Html.MaxLength(x => x.Name) })
@using HtmlHelper