MVC3はModelStateエラーを削除します


83

ユーザーがローカルファイルシステムから選択した画像をアップロードしている状況があります。私の見解では、私のフォームには基本的に2つの送信ボタンがあります。1つは通常どおりフォームを送信するために使用され、すべての検証が実行されます。2つ目は画像をアップロードするためだけのもので、その場合はまだ検証したくありません。

「画像のアップロード」送信ボタンに「style-namecancel」のクラス値を指定することで、クライアント側の検証をオフにすることができました。

<input type="submit" name="UploadImageButton" value="Upload Image" class="style-name cancel" /> 

これで、ポストバックすると、モデルにプロパティUploadImageButtonがあり、このボタンをクリックすると、このプロパティにデータが入力されます(入力の名前はプロパティと一致します)。このようにして、フォームが実際の送信ボタンによって送信されたのか、UploadImageButtonによって送信されたのかがわかります。

私の質問はこれです... ServerSide検証をオフにするにはどうすればよいですか?ユーザーがこのボタンをクリックしたときに検証の概要情報が表示されないようにします。これを使用してカスタムモデルエラーを追加できることを知っています

ModelState.AddModelError("{key}", "{error msg}");

モデルエラーを削除する方法を探しています。これは可能ですか?

編集:

これが私が思いついたものです:

foreach (var key in ModelState.Keys.ToList().Where(key => ModelState.ContainsKey(key))) {
     //ModelState.Remove(key); //This was my solution before
     ModelState[key].Errors.Clear(); //This is my new solution. Thanks bbak
}

なんでやってるのWhere(key => ModelState.Keys.Contains(key))?ModelState.Keysの各キーのModelState.Keys.Contains(key)がtrueを返すため、Where句は冗長であるように見えます。
マキシムザスラフスキー2011

1
ModelState.ContainsKeyで短いメソッドを使用するように質問とテキストを更新しましたが、あなたの仮定は間違っています。これらは同じことをしています。
Jeff Reddy 2011

申し訳ありませんが、説明が不十分であるか、返信を誤解している可能性があります。あなたことをしている権利ModelState.ContainsKey(key)ModelState.Contains(key)同じことを行うが、私のポイントは、内のすべての値であることをModelState.Keys.ToList()本質的に意志が中に含まれModelState、その全体のWhere句は冗長であり、パフォーマンスが低下します。ささいなことですが。
マキシムザスラフスキー2011

それはReSharperがそれを一緒に投げたものでした。それを指摘してくれてありがとう。
Jeff Reddy 2011

1
どのボタンが送信元であったかを見つける方法に注意してください。ViewModelでは、このプロパティを持っている必要はありません。FormCollectionパラメーターをコントローラーに追加するだけです:public ActionResult Index(YourViewModelClass model、FormCollectionformCollection)。そして、ボタン名が含まれているかどうかを確認します:if(formCollection ["UploadImageButton"]!= null)。送信ボタンが多い方がいいと思います。
jannagy02 2013年

回答:


145

次のような操作を行うことで、モデルエラーを削除できます。

if (ModelState.ContainsKey("{key}"))
    ModelState["{key}"].Errors.Clear();

1
これはまさに私が探していたものです。選択した回答を変更しました(申し訳ありませんが、Adam Tuliper)。
Jeff Reddy 2011

おかげで、それは私の数時間を節約しました!
agent007 2013年

1
誰かが疑問に思っていた場合に備えて、これも影響しますModelState.IsValid
Red Taz 2015

2
不思議なことに、私の場合、これでは十分ではありませんでした。ModelState ["{key}"]。ValidationState = ModelValidationState.Valid;を追加する必要がありました。
AGuyCalledGerald 2017年

67

これは以前の回答に基づいていますが、もう少し単純化しています。

foreach (var modelValue in ModelState.Values)
{
    modelValue.Errors.Clear();
}

7

一般に、サーバー側の検証をオフにしたり、ModelStateエラーを手動で削除したりすることは望ましくありません。それは実行可能ですが、キーとして文字列に依存する必要があるため、エラーが発生しやすくなります。キーを削除する方法は正しくて便利なので、私は答えを支持しましたが、それを強く考慮しなければならない場合に自分自身を設計することはお勧めしません。

あなたの場合、同じフォームに複数の送信ボタンがありますが、画像をアップロードするときに実際にはフォームを送信していません。クライアント側の検証を防ぐために、すでに示したように「キャンセル」クラスを使用できますが、2番目の送信ボタンを別のフォームにすることもお勧めします。その場合、メインフォームで検証が行われません。

別のフォームを使用することには2つ目の利点があります。それは、画像をアップロードするロジックを処理するだけの別のActionResultメソッドに送信できることです。この別の方法では、モデルの状態の「IsValid」プロパティを確認する必要はありません。画像に情報があるかどうかだけを考慮し、個別に確認できます。(同じActionResultメソッドを使用する場合でも、モデル状態のIsValidプロパティに依存しないように、ロジックをファネルすることができます。)

モデルの状態からエラーをクリアする必要があり、すべてのエラーをクリアすることが理にかなっている場合は、次のことを試してください。

foreach (var key in ModelState.Keys)
{
    ModelState[key].Errors.Clear();
}

これにより、キー名を正しく取得することに依存することはなくなりますが、モデルに値(有効または無効)がすでに存在する場合は値が保持されます。

このような場合に最後に確認する必要があるのは、ビューにたまにしか表示されない値があるかどうかです。これにより、クライアント側の検証は発生しませんが(ビューには表示されません)、サーバー側の検証の問題が発生します。この場合、@ Html.HiddenFor(model => model.PropertyNameを使用することをお勧めします。可能であれば、値がすでに設定されていると仮定すると、このビューには表示されません。


7

私は時々それを使うので、それから拡張メソッドを作りました:

public static ModelStateDictionary ClearError(this ModelStateDictionary m, string fieldName)
{
    if (m.ContainsKey(fieldName))
        m[fieldName].Errors.Clear();
    return m;
}

複数のフィールドのエラーをクリアするために流暢に使用できます。


3

ModelState.Remove( "{key}")を使用して、モデルからエラーを削除します。これにより、ModelState.IsValidがtrueにリセットされます。

ModelState.Remove("{key}");
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.