[〜#〜] edit [〜#〜]-MVC4 Dev Previewを使用しています...
FishingTrip
クラスの編集ページを実装しています。 FishingTrip
には、単純なCrew
オブジェクトの子コレクションが含まれます(例:FishingTripID、CrewID、CrewPosition)。
Jarrett Meyerのアプローチ を使用して、Crew
コレクションの追加、編集、削除を行っています。控えめな検証を使用して、Crew
のプロパティがすべてRequired
であることを指定しています。
私の問題:(Jarrettの方法に従って)リストから項目を論理的に削除するとき、その項目を検証したくありません。
論理的に削除されたアイテムの控えめな検証を無効にするために、クライアント側の「removeRow」メソッドを微調整し、空のフィールドを含むアイテムがあるにもかかわらずフォームが投稿されるようにしました。
私のコントローラーメソッド[HttpPost] Edit
、ModelState.IsValid
はfalseから始まります(予想どおり-空白のフィールドを含む論理的に削除されたアイテムのため)。したがって、ViewModelからそのアイテムを削除します。..ModelState.IsValid
はまだfalseです。
要約すると、コントローラーメソッド内でViewModelを変更して問題のあるアイテムを削除し、ある種の「再検証」を呼び出して、ModelState.IsValid
trueと表示されます。
何か案は?
問題のあるアイテムを削除したら、次のようにModelStateをクリアして再度検証します。
ModelState.Clear();
TryValidateModel(crew); // assumes the model being passed is named "crew"
注:TryValidateModel
メソッドを使用するときは注意してください。このメソッドは、モデルのネストされたオブジェクトを検証しないためです(@Merenzoが述べたように)。
ゲームに遅れましたが、それでも:モデルを検証する方法を探していましたafterモデル(より正確には-ネストされたコレクションのアイテム)-およびTryValidateModel
はネストされたオブジェクトを処理しないため、私にとってはうまくいきませんでした。
最後に、カスタムモデルバインダーで解決しました。
public class MyItemModelBinder : DefaultModelBinder
{
protected override void OnModelUpdated(
ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
if (bindingContext.ModelType == typeof(MyItemModel))
{
MyItemModel item = (MyItemModel)bindingContext.Model;
//do required tweaks on model here
//(I needed to load some additional data from DB)
}
//validation code will be called here, in OnModelUpdated implementation
base.OnModelUpdated(controllerContext, bindingContext);
}
}
モデルクラス:
[ModelBinder(typeof(MyItemModelBinder))]
public class MyItemModel : IValidatableObject
{
//...
}