から継承するカスタムモデルバインダーを作成しようとしていDefaultModelBinder
ます。この実装では、検証ルールのメタデータ(FluentValidationから)にアクセスします。これには、エラーメッセージをオーバーライドModelState
するために必要な情報が含まれているためです。
検証メッセージにリソースを使用していないため、そのリンクの回答は役に立ちません。メッセージはFluentValidationルールに保存されます。そのリンクの問題と同様に、通常の検証が機能しない理由は、.NETのモデルバインダーがメッセージを引き継いで設定し、値をnullにして、FluentValidationルールが有効である限り値を有効にするためです。心配している。
プロパティとルールごとにモデルの検証ルールにアクセスできれば、これを機能させることができます。
モデルの例を次に示します。
[Validator(typeof(SampleValidator))]
public SampleModel
{
public DateTime SomeDate { get; set; }
public int SomeInt { get; set; }
public decimal SomeDecimal { get; set; }
}
FluentValidationは、そのままではデータ型の検証を提供しないため、(Fluentアダプターを介して)検証メッセージをオーバーライドする独自のクライアント側バリデーターを構築しました。私の問題は、そのリンクされた議論で述べられているように、.NETのデフォルトのモデルバインダーによって引き継がれるサーバー側の検証にあります。
DefaultModelBinder.SetPropertyオーバーライドからこれを実行しようとしています。
protected override void SetProperty(
ControllerContext controllerContext,
ModelBindingContext bindingContext,
System.ComponentModel.PropertyDescriptor propertyDescriptor,
object value)
{
}
これがバリデーターのサンプルです。上で述べたように、サーバー側の検証IsValid
では常にtrue bacuaseが返されますDefaultModelBinder
。日付以外が入力されると、常に値がnullに上書きされます。
public class DateValidator : PropertyValidator, IDateValidator
{
public DateValidator()
: base(() => "{PropertyName} must be a date.")
{
}
protected override bool IsValid(PropertyValidatorContext context)
{
return true;
}
}
検証アダプターは、バリデーターをクライアント側のアダプターとパラメーターに接続するだけです。
public class DateFluentValidationPropertyValidator : FluentValidationPropertyValidator
{
private IDateValidator DateValidator
{
get { return (IDateValidator)Validator; }
}
public DateFluentValidationPropertyValidator(ModelMetadata metadata, ControllerContext controllerContext, PropertyRule rule, IPropertyValidator validator)
: base(metadata, controllerContext, rule, validator)
{
ShouldValidate = false;
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
if (!ShouldGenerateClientSideRules()) yield break;
var formatter = new MessageFormatter().AppendPropertyName(Rule.GetDisplayName());
string message = formatter.BuildMessage(DateValidator.ErrorMessageSource.GetString());
yield return new ModelClientValidationRule
{
ValidationType = "date",
ErrorMessage = message
};
}
}
そして、これが私がどのようにプロパティをルールに結び付けるかです:
public class SampleValidator : AbstractValidator<SampleModel>
{
public SampleValidator()
{
this.RuleFor(m => m.SomeDate).Date();
}
}
これらの値を使用して、モデルの検証ルールとメタデータにアクセスするにはどうすればよいですか?