MVAがModelAnnotation属性(必須または範囲など)を最初に実行し、それらのいずれかが失敗した場合、IValidatableObjectモデルでValidateメソッドをスキップしてモデルを検証すると思われます。MVCにIValidatableObjectの検証を強制する方法
MVCは先に行くと、他の検証が失敗した場合でも、その方法を実行させる方法はありますか?
MVAがModelAnnotation属性(必須または範囲など)を最初に実行し、それらのいずれかが失敗した場合、IValidatableObjectモデルでValidateメソッドをスキップしてモデルを検証すると思われます。MVCにIValidatableObjectの検証を強制する方法
MVCは先に行くと、他の検証が失敗した場合でも、その方法を実行させる方法はありますか?
:
[HttpPost]
public ActionResult Create(Model model) {
if (!ModelState.IsValid) {
var errors = model.Validate(new ValidationContext(model, null, null));
foreach (var error in errors)
foreach (var memberName in error.MemberNames)
ModelState.AddModelError(memberName, error.ErrorMessage);
return View(post);
}
}
このアプローチの注意点は、その(DataAnnotation)エラーなし性レベルが存在しない場合において検証は2回実行されます。それを避けるために、あなたはあなたのモデルにプロパティを追加することができ、それが実行され、その後、手動でコントローラにメソッドを呼び出す前に確認したら、あなたのvalidate()メソッドでtrueに設定ブール検証済みの、と言います。だからあなたのコントローラで
:
if (!ModelState.IsValid) {
if (!model.Validated) {
var validationResults = model.Validate(new ValidationContext(model, null, null));
foreach (var error in validationResults)
foreach (var memberName in error.MemberNames)
ModelState.AddModelError(memberName, error.ErrorMessage);
}
return View(post);
}
そして、あなたのモデルでは:
public bool Validated { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
// perform validation
Validated = true;
}
ありがとうございました。しかし、私は1つの質問を得ました.Ivalidate Objectが発砲しているので何らかの理由がありますか?いつかそれはできないかもしれない? – user998405
各コントローラのアクションの先頭に定型的なコードを必要とせずにそれを行うための方法があります。
あなたがあなた自身のものとデフォルトのモデルバインダーを交換する必要があります:
protected void Application_Start()
{
// ...
ModelBinderProviders.BinderProviders.Clear();
ModelBinderProviders.BinderProviders.Add(new CustomModelBinderProvider());
// ...
}
あなたのモデルバインダープロバイダーは、次のようになります。
public class CustomModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(Type modelType)
{
return new CustomModelBinder();
}
}
さて、実際にカスタムモデルバインダーを作成します検証を強制する。ここで重労働が行われます:
また、IndexOf拡張メソッドも必要です。これは安価な実装ですが、動作します:
public static int IndexOf<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
if (source == null) throw new ArgumentNullException("source");
if (predicate == null) throw new ArgumentNullException("predicate");
var i = 0;
foreach (var item in source)
{
if (predicate(item)) return i;
i++;
}
return -1;
}
正に、私はこのデフォルトの動作が気に入っています。データベース接続のような高価なものが含まれるValidateメソッドでビジネスレベルの検証を行う場合、モデルが有効でない限り呼び出さないほうがよいです。 – Graham