Как создать собственный Валидатор для проверки замка на стороне клиента? - PullRequest
1 голос
/ 13 января 2012

Я использую проверку замка, и я хотел бы знать, почему мой валидатор не работает:

[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 - нет.

Я видел эту тему Мин. Длина Пользовательский AbstractValidationAttribute и реализующий Castle.Components.Validator.IValidator , но я не вижу никакой разницы между моим кодом и его.

1 Ответ

1 голос
/ 20 января 2012

Я наконец нашел его после просмотра исходного кода 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));
    }
}

Валидатор предоставляет некоторую функциональность для добавления пользовательской проверки Валидатор, который необходим помощнику по формам:

 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, но это решение не самое лучшее, но я не смог выяснить, как внедрить его в конфигурацию монорельса замка.

Я постараюсь передать это на базу монорельсового замка ...

...