Mik*_*ole 7 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; }
Run Code Online (Sandbox Code Playgroud)
在我看来:
@Html.EditorFor(model => model.Extension)
Run Code Online (Sandbox Code Playgroud)
它呈现:
<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="" />
Run Code Online (Sandbox Code Playgroud)
这应该在我的文本框上设置maxlength属性吗?如果没有,我怎么能用DataAttributes做到这一点?
本质上基于 Brad 的答案,使用 lambda 语法包装在 Html 帮助器的扩展中,这样你就不会用反射内容污染你的 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;
}
}
Run Code Online (Sandbox Code Playgroud)
像这样使用它:
@Html.TextBoxFor(x => x.Name, new { maxlength = Html.MaxLength(x => x.Name) })
Run Code Online (Sandbox Code Playgroud)
其中x指的是您的型号。
如果StringLengthAttribute未为属性声明 ,null则将返回,并且maxlength文本框元素上的属性将为空。
请记住在您的 razor 页面中包含 using ,以便您可以访问该方法。
@using HtmlHelper
Run Code Online (Sandbox Code Playgroud)
您还需要对该方法使用不可为空的结果来克服编译错误。
如果可能的话,我希望在 ViewModel 中设置的属性来控制它。
ASP.NET MVC 提供了一个可扩展的系统来完成此任务。这是您需要做的:
ModelMetadataProvider.StringLengthAttribute或 the MaxLengthAttribute,提取信息并将其添加到 中ModelMetadata。步骤 1:实施自定义ModelMetadataProvider.
创建一个派生自 的类ModelMetadataProvider。通常您会从 派生,DataAnnotationsModelMetadataProvider因为它提供了一些默认功能,这意味着您只需重写一个名为 的方法CreateMetadata。
第二步:提取信息:
要获取该信息,您需要查找该属性,提取最大长度信息并将其添加AdditionalValues到ModelMetadata. 实现看起来像这样(这是整个实现):
public class CustomModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(
IEnumerable<Attribute> attributes,
Type containerType,
Func<object> modelAccessor,
Type modelType,
string propertyName)
{
// Call the base class implementation to create the default metadata...
var metadata = base.CreateMetadata(
attributes,
containerType,
modelAccessor,
modelType,
propertyName);
// Extract the stringLengthAttribute (you can do the same for the
// MaxLengthAttribute if you want).
var attr = attributes
.OfType<StringLengthAttribute>()
.First();
// This could be getting called on a property that doesn't have the
// attribute so make sure you check for null!
if (attr != null)
{
metadata.AdditionalValues["maxLength"] = attr.MaximumLength;
}
return metadata;
}
}
Run Code Online (Sandbox Code Playgroud)
为了让 ASP.NET MVC 使用它,您需要Application_Start在Global.asax.
ModelMetadataProviders.Current = new CustomModelMetadataProvider();
Run Code Online (Sandbox Code Playgroud)
步骤 3:创建自定义编辑器模板。
您现在需要创建一个使用该信息的视图。String在文件夹中创建一个名为的新视图Views\Shared\。
字符串.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)
Run Code Online (Sandbox Code Playgroud)
当您运行应用程序时,您将通过调用获得以下 HTML 输出@Html.EditorFor。
<input class="text-box single-line" id="Extension" maxlength="6" name="Extension" type="text" value="" />
Run Code Online (Sandbox Code Playgroud)
如果您想了解有关模型元数据提供程序系统的更多信息,Brad Wilson 有一系列博客文章,详细介绍了它的工作原理(这些文章是在 Razor 视图引擎之前编写的,因此某些视图语法有点时髦,但除此之外,信息是声音)。