C# 子属性的选择性验证-MVC中的Fluent验证

C# 子属性的选择性验证-MVC中的Fluent验证,c#,asp.net-mvc,ninject,fluentvalidation,C#,Asp.net Mvc,Ninject,Fluentvalidation,我在Ninject.Web.Mvc.FluentValidation库中使用Fluent验证来自动连接我的所有验证器(并使用依赖注入来创建验证器) 我创建了以下模型: public class Parent { public string Name { get; set; } public Child Child1 { get; set; } public Child Child2 { get; set; } } public class Child { pu

我在Ninject.Web.Mvc.FluentValidation库中使用Fluent验证来自动连接我的所有验证器(并使用依赖注入来创建验证器)

我创建了以下模型:

public class Parent
{
    public string Name { get; set; }

    public Child Child1 { get; set; }
    public Child Child2 { get; set; }
}

public class Child
{
    public string ChildProperty { get; set; }
}
使用以下验证器:

public class ParentValidator : AbstractValidator<Parent>
{
    public ParentValidator()
    {
         RuleFor(model => model.Name).NotEmpty();
         RuleFor(model => model.Child1).SetValidator(new ChildValidator());
    }
}

public class ChildValidator : AbstractValidator<Child>
{
    public ChildValidator()
    {
        RuleFor(model => model.ChildProperty).NotEmpty();
    }
}
公共类ParentValidator:AbstractValidator { 公共ParentValidator() { RuleFor(model=>model.Name).NotEmpty(); RuleFor(model=>model.Child1).SetValidator(新的ChildValidator()); } } 公共类ChildValidator:AbstractValidator { 公共儿童验证器() { RuleFor(model=>model.ChildProperty).NotEmpty(); } } 我的看法:

@model Parent

@using(Html.BeginForm())
{
    @Html.EditorFor(model => model.Name)
    @Html.ValidationMessageFor(model => model.Name)

    @Html.EditorFor(model => model.Child1)
    @Html.EditorFor(model => model.Child2)

    <input type="submit" value="Save" />
}

@model Child

@Html.EditorFor(model => model.ChildProperty)
@Html.EditorFor(model => model.ChildProperty)
@模型父级
@使用(Html.BeginForm())
{
@EditorFor(model=>model.Name)
@Html.ValidationMessageFor(model=>model.Name)
@EditorFor(model=>model.Child1)
@EditorFor(model=>model.Child2)
}
@模范儿童
@EditorFor(model=>model.ChildProperty)
@EditorFor(model=>model.ChildProperty)
我试图实现的是拥有一个具有两个子属性的父模型。Child1的属性是必需的,但Child2的属性是可选的。这在正常情况下可以正常工作,但当我使用Ninject模块自动连接验证器时,它会检测到子类有验证器类型,并连接父类上的所有子属性


有没有什么方法可以在不删除Ninject模块的情况下防止这种情况发生?

由于自动连线无法有条件地理解在模型绑定期间何时应用ChildValidator类,因此您似乎有一些选择:

  • 决定重用子视图模型是否如此重要。面对这种情况,如果子对象不是非常复杂,并且没有多个单独使用子对象的视图,我可能会将子视图折叠到该视图的父视图中。我总是有点不愿意对视图模型过于枯燥,因为根据我的经验,页面结构往往会随着时间的推移而发生变化
  • 从这里,您可以完全控制Child2的验证,包括在这个独特的上下文中为Child2提供一个单独的验证器,并手动应用它。这也是我喜欢FluentValidation的原因之一——它能够在不同的上下文中将不同的验证逻辑应用于同一视图模型,而不像数据注释

  • auto wireup的值(即它排除的所有额外代码)将排除在这种情况下关闭该选项的可能性,依我看。

    您忘记将validator设置为第二个子属性:

    public class ParentValidator : AbstractValidator<Parent>
    {
        public ParentValidator()
        {
             RuleFor(model => model.Name).NotEmpty();
             RuleFor(model => model.Child1).SetValidator(new ChildValidator());
             RuleFor(model => model.Child2).SetValidator(new ChildValidator());
        }
    }
    
    公共类ParentValidator:AbstractValidator { 公共ParentValidator() { RuleFor(model=>model.Name).NotEmpty(); RuleFor(model=>model.Child1).SetValidator(新的ChildValidator()); RuleFor(model=>model.Child2).SetValidator(新的ChildValidator()); } }
    如果不想自动连接子验证程序,可以将空接口添加到子验证程序:

    公共类PersonalDataValidator:AbstractValidator、IChildValidator

    然后在你的工厂里:

    public class FluentValidatorFactory : ValidatorFactoryBase
    {
        private readonly IKernel _kernel;
    
        public FluentValidatorFactory(IKernel kernel)
        {
            _kernel = kernel;
        }
    
        public override IValidator CreateInstance(Type validatorType)
        {
            IValidator validator = _kernel.Resolve(validatorType) as IValidator;
    
            ////we dont want that windosr auto wires up all child validators. 
            var childValidator = validator as IChildValidator;
    
            if (childValidator == null)
            {
                return validator;
            }
    
                return null;
        }
    }
    

    我不需要这样做,因为我使用的是一个Ninject模块,可以自动连接我程序集中的所有验证器。