如果可能的话,我希望我在 ViewModel 中设置的属性来控制它。
ASP.NET MVC 为此提供了一个可扩展的系统。这是您需要做的:
- 实现一个自定义
ModelMetadataProvider
.
- 查找
StringLengthAttribute
或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;
}
}
为了让 ASP.NET MVC 使用它,您需要Application_Start
在Global.asax
.
ModelMetadataProviders.Current = new CustomModelMetadataProvider();
第 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)
当您运行您的应用程序时,您将通过调用获得以下 HTML 输出@Html.EditorFor
。
<input class="text-box single-line" id="Extension" maxlength="6" name="Extension" type="text" value="" />
如果您想了解有关模型元数据提供程序系统的更多信息,Brad Wilson 有一系列博客文章详细说明了它是如何工作的(这些是在 Razor 视图引擎之前编写的,因此某些视图语法有点时髦,但除此之外的信息是声音)。