asp.net-mvc-3 - 带验证的独立组件

标签 asp.net-mvc-3 validation model-binding

我有一个名为 Foo 的模型,它有一个名为 MyProp 的类型 Bar 的属性。 当我将此模型发布到 Controller 时,我希望模型绑定(bind)器验证 MyProp,因为它具有所需属性,就像它对字符串一样。我需要它在 Bar 类中独立存在或作为一个单独的类。我尝试在 Bar 类上使用 IValidatableObject,但似乎无法检查 Foo 类是否具有 Required 属性 <强>我的属性(property)?所以现在我别无选择,需要一些帮助。下面是我的问题的一些示例代码。

public class Foo {
    [Required]
    public Bar MyProp { get; set; }
}

public class Bar {
    [ScaffoldColumn(false)]
    public int Id { get; set; }
    public string Name { get; set; }
}

最佳答案

这是解决我的问题的一种解决方案,我可以使用内置的必需属性并仍然获得自定义行为。这只是一些概念验证代码。

型号:

public class Page : IPageModel {
    [Display(Name = "Page", Prompt = "Specify page name...")]
    [Required(ErrorMessage = "You must specify a page name")]
    public PageReference PageReference { get; set; }
}

模型绑定(bind)器:

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);
    }
}

模型绑定(bind)器提供者:

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

那么您对此解决方案有何看法?

关于asp.net-mvc-3 - 带验证的独立组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11889357/

相关文章:

asp.net-mvc-3 - ASP.NET MVC 3 : - Using database instead of resource files as the localization store

c# - 如何在 MVC3 中将嵌套的 ViewModel 从 View 绑定(bind)到 Controller?

jquery - 如果用户单击 "Cancel"按钮,Ajax.Actionlink OnBegin 确认不会阻止调用 ajax 调用

.net - 在 Ajax.Beginform 的 OnComplete 事件函数中接收 JSON 数据

wpf - 在 M-V-VM 中使用 IDataErrorInfo

asp.net-mvc - 使用模型绑定(bind)从 MVC 4 中的 List<T> 中选择项目

asp.net-mvc-3 - 在同一父 View 上多次使用一个局部 View

ruby-on-rails - 你能把一个变量放在正则表达式中吗?

c++ - 使用cin在C++中进行输入验证的最佳方法是什么?

asp.net-mvc - MVC 5 中的 TryUpdate() 和 Update() 方法有什么区别吗?