Comment construire un validateur personnalisé pour le château de validation sur côté client?

StackOverflow https://stackoverflow.com/questions/8853768

  •  28-10-2019
  •  | 
  •  

Question

J'utilise la validation du château et je voudrais savoir pourquoi mon validateur ne fonctionne pas:

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

Et mon champ

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

Et moi

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

Le validate ValidateNonEmpty à la fois côté client et serveur, mais le ValidatePositiveInteger n'est pas.

Je l'ai vu ce fil , mais je ne vois aucune différence entre mon code et son.

Était-ce utile?

La solution

J'ai finalement trouvé après avoir parcouru le code source de validation Castle:

La validation par défaut est PrototypeWebValidator, et ce validateur utilise PrototypeValidationGenerator pour la validation du côté client, et cette mise en œuvre ne fait rien lorsque vous appelez « SetValueRange »:

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

qui semble logique que ma validation côté client ne fonctionne pas (le PrototypeValidationGenerator n'a pas mis en œuvre cette fonctionnalité principalement parce que l'API de validation sous-jacente, https://github.com/atetlaw/Really-Easy-Field-Validation n'a pas impement aussi bien).

Je décidé d'étendre ce parce qu'il est un cadre et il est l'objet d'un cadre: fournir un cadre et vous permettent de travailler dans ce

.

Je créé le générateur

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

Le validateur fournit une fonctionnalité pour ajouter une validation personnalisée Le validateur qui est nécessaire par le FormHelper:

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

Et vous château fil à votre validateur sur votre contrôleur de base comme ceci:

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

J'ai un BaseController mais cette solution est le meilleur, mais je ne pouvais pas savoir comment injecter dans la configuration du monorail du château.

Je vais essayer de commettre ce à la base de la source du château Monorail ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top