我希望我在 ViewModel 中设置的属性来控制它,如果
可能。
ASP.NET MVC 提供了一个可扩展的系统来实现这一点。以下是您需要做的:
- 实现自定义
ModelMetadataProvider。
- 查找
StringLengthAttribute 或MaxLengthAttribute,提取信息并将其添加到ModelMetadata。
- 提供一个使用这些信息的自定义编辑器模板。
第 1 步:实现自定义 ModelMetadataProvider。
创建一个派生自ModelMetadataProvider 的类。通常您会从 DataAnnotationsModelMetadataProvider 派生,因为它提供了一些默认功能,这意味着您只需覆盖一个名为 CreateMetadata 的方法。
第 2 步:提取信息:
要获取信息,需要查找属性,提取最大长度信息,并将其添加到ModelMetadata 的AdditionalValues 字典中。实现看起来像这样(这是整个实现):
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 使用它,您需要在 Global.asax 的 Application_Start 方法中注册它。
ModelMetadataProviders.Current = new CustomModelMetadataProvider();
第 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="" />
如果您想了解有关模型元数据提供程序系统的更多信息,Brad Wilson has a series of blog posts 详细说明它是如何工作的(这些是在 Razor 视图引擎之前编写的,因此某些视图语法有点时髦,但其他信息是合理的)。