クライアント側でキャッスル検証用のカスタムバリデーターを構築する方法は?
-
28-10-2019 - |
質問
私はCastle Balidationを使用していますが、なぜ私のValibatorが機能していないのか知りたいです。
[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'}")
valimatenonemptyはクライアント側とサーバー側の両方で検証しますが、ValidatePositiveIntegerはそうではありません。
私はこのスレッドを見ました 最小長さのabstractValidationAttributeと実装caster.components.validator.ivalidator 、しかし、私のコードと彼のコードの違いはわかりません。
解決
キャッスル検証ソースコードを閲覧した後、ついにそれを見つけました:
デフォルトの検証はprototypewebvalidatorであり、このValidatorはクライアント側の検証にPrototypevalidationGeneratorを使用します。
public void SetValueRange(string target, int minValue, int maxValue, string violationMessage)
{
}
そのため、私のクライアント側の検証が機能していないことは論理的に思えます(主に基礎となる検証APIのために、プロトタイプエバイディングGeneratorはこの機能を実装しませんでした。 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));
}
}
VALIBARATORは、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());
// ...
}
私はベースコントローラーを持っていますが、このソリューションは最高ではありませんが、Castle Monorailの構成にそれを注入する方法を見つけることができませんでした。
キャッスルモノレールのソースベースにこれをコミットしようとします...