私の問題はバインディングではなく、実際には検証に関係していることを認識しています。値を保持することは、ユーザーがページをリロードしたときに同じフォームフィールドにデータが入力されることを意味します。該当する。
そのために、モデル プロパティの検証を実行できることに気付きましたが、カスタム ロジックを使用して検証メッセージを削除しました。これは私がやったことと似ています:
public class CaseModel {
public void CleanValidation(ModelStateDictionary dict) {
if( this.ClientPresent ) {
dict.Keys.All( k => if( k.StartsWith("Client") dict[k].Errors.Clear() );
}
}
}
(明らかに、私の実際のコードはより堅牢ですが、一般的な考え方は理解できます)
CleanValidation メソッドは、コントローラーのアクション メソッドによって直接呼び出されます。
public void Edit(Int64 id, CaseModel model) {
model.CleanValidation( this.ModelState );
}
CleanValidation
新しいインターフェイスにメソッドとして追加し、新しいモデル バインダーがこのメソッドを自動的に呼び出すようにすることで、おそらくこれを整理できるIComplexModel
ので、コントローラーがそれ自体を呼び出す必要はありません。
アップデート:
複雑な検証が必要な ViewModel に適用されるこのインターフェイスがあります。
public interface ICustomValidation {
void Validate(ModelStateDictionary dict);
}
私の元の例では、CaseModel
次のようになります。
public class CaseClientModel : ICustomValidation {
public Boolean ClientIsNew { get; set; } // bound to a radio-button
public ClientModel ExistingClient { get; set; } // a complex viewmodel used by a partial view
public ClientModel NewClient { get; set; } // ditto
public void Validate(ModelStateDictionary dict) {
// RemoveElementsWithPrefix is an extension method that removes all key/value pairs from a dictionary if the key has the specified prefix.
if( this.ClientIsNew ) dict.RemoveElementsWithPrefix("ExistingClient");
else dict.RemoveElementsWithPrefix("NewClient");
}
}
検証ロジックはOnActionExecuting
、私の共通BaseController
クラスで呼び出されます。
protected override void OnActionExecuting(ActionExecutingContext filterContext) {
base.OnActionExecuting(filterContext);
if( filterContext.ActionParameters.ContainsKey("model") ) {
Object model = filterContext.ActionParameters["model"];
ModelStateDictionary modelState = filterContext.Controller.ViewData.ModelState; // ViewData.Model always returns null at this point, so do this to get the ModelState.
ICustomValidation modelValidation = model as ICustomValidation;
if( modelValidation != null ) {
modelValidation.Validate( modelState );
}
}
}