2012-10-29 16 views
6

私はmvc 4で書かれたプロジェクトに取り組んでいます。これは、ウィザードのような動作のいくつかのインスタンスを持っています。 2番目のビューから開始して、コントロールは最初は有効でないものとして表示されます(これは論理モデルであり、コントローラメソッドに渡されると対応するプロパティが空になります)。現在は ModelState.Clear(); の解を使用していますが、モデルを引数として各メソッドに入れるのは醜いです。アプローチと同じことが、ここでDisable Model Validation in Asp.Net MVCMVC 4モデル検証を無効にするにはどうすればよいですか?

ModelBinders.Binders[typeof(MyModelType)] = new NonValidatingModelBinder(); 

を発見したプロジェクトは、手動で各1を登録するには(100以上)あまりにも多くのモデルクラスを得ました。

モデルの検証を完全に無効にする簡単な方法がありますか?

+3

は個人的に、私は、各ウィザードステップのための別のビューモデルを使用したいと思います。これにより、必要な場所(つまり、現在のウィザードステップの値)で検証を使用することができます。 –

答えて

8

を追加することを忘れないでくださいしかし、あなたは、私はそれがない知っているこの(ブートストラップコードまたはGlobal.asaxの)

ModelValidatorProviders.Providers.Clear(); 
+0

私はそれをチェックしました。このコードは機能します。私のプロジェクトでは、クリアされたコレクションから 'DataAnnotationsModelValidatorProvider'によって作成されたバリデータがクライアント側のバリデーター(デフォルト" * "の代わりに)のErrorMessageを取得するために使用されたため、使用できません。 これは私の質問に対する最も単純な答えです。 – user1782982

+0

これは私のためには機能しません、なぜ私は理解していません –

2

私はweb.configなどのすべてのオプションについてはわかりません。

Assembly.GetExecutingAssembly() 
    .GetTypes() 
    .Where(t => t.IsClass && t.Namespace == "Your.Name.Space") 
    .ToList() 
    .ForEach(t => ModelBinders.Binders[t] = new NonValidatingModelBinder()); 

それとも

typeof(MyModelType) 
    .Assembly 
    .GetTypes() 
    .Where(t => t.IsClass && t.Namespace == "Your.Name.Space") 
    .ToList() 
    .ForEach(t => ModelBinders.Binders[t] = new NonValidatingModelBinder()); 

それともNonValidatingModelBinderにあなたのアセンブリ内すべてクラスを追加しますので&& t.Namespace == "Your.Name.Space"一部を削除します。しかし、あなたはこれを使用することができます。

は、私はこれが仕事ができることを知らないusing System.Linq;

4

を試してみました本当にあなたの質問に答えるが、ちょうど私のコメントに展開する: - :

public class MyModel 
{ 
    [Required] 
    public string Foo { get; set; } // Populated in step 1 
    [Required] 
    public string Bar { get; set; } // Populated in step 2 
} 
-

それはあなたのようなものを持っているように聞こえます

ユーザーがまだBarの値を入力していないため、ステップ1をPOSTするときに問題が発生しました。したがって、ModelStateErrorがあります。

私の好適な解決策ではなく、自分の永続化モデルの検証と周り台無しにしようとするよりも、例えば、各ウィザードステップのためのViewModelを使用してモデルの実装から、あなたのビューの実装を分離するために、次のようになります -

public class MyModel 
{ 
    [Required] 
    public string Foo { get; set; } 
    [Required] 
    public string Bar { get; set; } 
} 

public class StepOneModel 
{ 
    [Required] 
    public string Foo { get; set; } 
} 

public class StepTwoModel 
{ 
    // This really depends on the behaviour you want. 
    // In this example, the model isn't persisted until 
    // the last step, but you could equally well persist 
    // the partial model server-side and just include a 
    // key in subsequent wizard steps. 
    [Required] 
    public StepOneModel StepOne { get; set; } 

    [Required] 
    public string Bar { get; set; } 
} 

@model StepOneModel 
@using (html.BeginForm()) { 
    @html.EditorFor(x => x.Foo); 
} 
- :あなたは、StepOneビューのようなものに見える

public ActionResult StepOne() 
{ 
    return View(new StepOneViewModel()); 
} 
[HttpPost] 
public ActionResult StepOne(StepOneViewModel model) 
{ 
    if(ModelState.IsValid) 
    { 
    var stepTwoModel = new StepTwoViewModel() 
    { 
     StepOne = model 
    }; 

    // Again, there's a bunch of different ways 
    // you can handle flow between steps, just 
    // doing it simply here to give an example 
    return View("StepTwo", model); 
    } 

    return View(model); 
} 
[HttpPost] 
public ActionResult StepTwo(StepTwoViewModel model) 
{ 
    if (ModelState.IsValid) 
    { 
    // You could also add a method to the final ViewModel 
    // to do this mapping, or use something like AutoMapper 
    MyModel model = new MyModel() 
    { 
     Foo = model.StepOne.Foo 
     Bar = model.Bar 
    }; 

    this.Context.MyModels.Add(model); 
    this.Context.SaveChanges(); 
    } 

    return View(model); 
} 

- :

あなたのコントローラのアクションは次のようになり

あなたStepTwoビューは次のようになります - ちょうどモデルの検証をオフに比べて大きな利点は、あなたのViewModelに現在のステップのための検証要件を置くことができるということです

@model StepTwoModel 
@using (html.BeginForm("StepTwo")) { 
    @html.HiddenFor(x => x.StepOne); 
    @html.EditorFor(x => x.Bar); 
} 

を - あなたはそのすべてを保証することができますステップ1からの値は、ステップ2に進む前に有効です。あなたはより多くのRESTfulなアプローチをしたい場合は

  • 別の一般的なソリューションは、<のdiv >クライアント側の各ステップをラップすることです(あなたのコントローラは、データがウィザード形式のビューから来ていることを気にしない場合)ユーザーの進行に合わせてjavascriptを使用して表示/非表示にします。

  • モデルをステップ間で永続化する必要がある場合は、モデルのValidationAttributesとその意味について考える必要があります。 User.DateOfBirthRequiredと注釈を付けたが、ステップが入る前に永続化できる必要がある場合は、実際にはUser.DateOfBirthではありません(たとえば、EF CodeFirstではNOT NULLにすることはできませんその間にヌル値を保持できるようにする)。後で完全なモデルを検証するには、いくつかの条件付き検証(例:IValidatableObjectMvcFoolproofFluent Validation)を行う必要があります。

+0

+1イアン - 素敵な要約:) –

0
@{ 
HtmlHelper.ClientValidationEnabled = false; 
} 
関連する問題