1

我正在使用城堡验证,我想知道为什么我的验证器不工作:

[Serializable]
    public class PositiveIntegerValidator : AbstractValidator
    {


    public override bool IsValid(object instance, object fieldValue)
    {
        if (fieldValue == null || !(fieldValue is int))
            return false;
        return ((int)fieldValue) > 0;
    }

    public override bool SupportsBrowserValidation
    {
        get { return true; }
    }

    public override void ApplyBrowserValidation(BrowserValidationConfiguration config, InputElementType inputType, IBrowserValidationGenerator generator, System.Collections.IDictionary attributes, string target)
    {
        base.ApplyBrowserValidation(config, inputType, generator, attributes, target);


        generator.SetValueRange(target, 0,int.MaxValue, ErrorMessage);
    }

    protected override string BuildErrorMessage()
    {
        return ErrorMessage;
    }
}
public class ValidatePositiveIntegerAttribute : AbstractValidationAttribute
{
    public ValidatePositiveIntegerAttribute(string msg) :base(msg){}
    public override IValidator Build()
    {
        PositiveIntegerValidator positiveIntegerValidator = new PositiveIntegerValidator();
        ConfigureValidatorMessage(positiveIntegerValidator);
        return positiveIntegerValidator;
    }
}

还有我的领域

  public class PackageViewModel
        {
//            ...
            [ValidateNonEmpty,ValidatePositiveInteger("The package count must be positive")]
            public int nbPackage { get; set; }
//...
}

而我的看法

 $FormHelper.TextField("package.nbPackage","%{size='3',value='1'}")

ValidateNonEmpty 在客户端和服务器端都进行验证,但 ValidatePositiveInteger 不是。

我看过这个线程Min Length Custom AbstractValidationAttribute 和 Implementing Castle.Components.Validator.IValidator,但我看不出我的代码和他的代码有什么区别。

4

1 回答 1

1

浏览Castle Validation源码后终于找到了:

默认验证是 PrototypeWebValidator,这个验证器使用 PrototypeValidationGenerator 进行客户端验证,当你调用 "SetValueRange" 时这个实现不做任何事情:

  public void SetValueRange(string target, int minValue, int maxValue, string violationMessage)
      {
      }

所以这似乎是合乎逻辑的,我的客户端验证不起作用(PrototypeValidationGenerator 没有实现这个功能,主要是因为底层的验证 API,https: //github.com/atetlaw/Really-Easy-Field-Validation 没有阻碍它以及)。

所以我决定扩展它,因为它是一个框架,它是框架的目的:提供一个框架并让你在其中工作。

所以我创建了生成器

public class PrototypeValidationGeneratorExtension : PrototypeWebValidator.PrototypeValidationGenerator
{
    private PrototypeWebValidator.PrototypeValidationConfiguration _config;
    public PrototypeValidationGeneratorExtension(PrototypeWebValidator.PrototypeValidationConfiguration config, InputElementType inputType, IDictionary attributes)
        :base(config,inputType,attributes)
    {
        _config = config;
    }
    public new void SetValueRange(string target, int minValue, int maxValue, string violationMessage)
    {
                    this._config.AddCustomRule("validate-range",violationMessage,string.Format("min : {0}, max : {1}", minValue, maxValue));
    }
}

验证器提供了一些添加自定义验证的功能 formhelper 所需的验证器:

 public class PrototypeWebValidatorExtension : PrototypeWebValidator
{
    public new IBrowserValidationGenerator CreateGenerator(BrowserValidationConfiguration config, InputElementType inputType, IDictionary attributes)
    {
        return new PrototypeValidationGeneratorExtension((PrototypeWebValidator.PrototypeValidationConfiguration)config, inputType, attributes);
    }
}

然后你将城堡连接到基本控制器上的验证器,如下所示:

        protected override void Initialize()
        {
            ((FormHelper)this.Helpers["Form"]).UseWebValidatorProvider(new PrototypeWebValidatorExtension());
//    ...
    }

我有一个 BaseController 但这个解决方案不是最好的,但我不知道如何将它注入到城堡单轨列车的配置中。

我将尝试将其提交给 Castle Monorail 的源代码库...

于 2012-01-20T16:15:54.450 回答