这是我的问题的一种解决方案,我可以使用内置的 required 属性并仍然获得自定义行为。这只是一些概念验证代码。
该模型:
public class Page : IPageModel {
[Display(Name = "Page", Prompt = "Specify page name...")]
[Required(ErrorMessage = "You must specify a page name")]
public PageReference PageReference { get; set; }
}
模型粘合剂:
public class PageModelBinder : DefaultModelBinder {
protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) {
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(bindingContext.ModelType)) {
var attributes = property.Attributes;
if (attributes.Count == 0) continue;
foreach (var attribute in attributes) {
if (attribute.GetType().BaseType == typeof(ValidationAttribute) && property.PropertyType == typeof(PageReference)) {
var pageReference = bindingContext.ModelType.GetProperty(property.Name).GetValue(bindingContext.Model, null) as PageReference;
Type attrType = attribute.GetType();
if (attrType == typeof (RequiredAttribute) && string.IsNullOrEmpty(pageReference.Name)) {
bindingContext.ModelState.AddModelError(property.Name,
((RequiredAttribute) attribute).ErrorMessage);
}
}
}
}
base.OnModelUpdated(controllerContext, bindingContext);
}
}
模型绑定器提供程序:
public class InheritanceAwareModelBinderProvider : Dictionary<Type, IModelBinder>, IModelBinderProvider {
public IModelBinder GetBinder(Type modelType) {
var binders = from binder in this
where binder.Key.IsAssignableFrom(modelType)
select binder.Value;
return binders.FirstOrDefault();
}
}
最后是 global.asax 注册:
var binderProvider = new InheritanceAwareModelBinderProvider {
{
typeof (IPageModel), new PageModelBinder() }
};
ModelBinderProviders.BinderProviders.Add(binderProvider);
结果:http ://cl.ly/IjCS
那么您如何看待这个解决方案?