6

私は、mvc 4 で書かれたプロジェクトに取り組んでおり、ウィザードのような動作のインスタンスがいくつかあります。つまり、同じ半分満たされたモデルを渡すいくつかのビューのチェーンです。2 番目のビュー コントロールから始めて、最初は無効として表示されます (これは論理モデルであり、コントローラー メソッドに渡された対応するプロパティは空です)。現在 ModelState.Clear(); は解決策が使われていますが、モデルを引数として各メソッドに入れるのは見栄えが悪いです。ここにあるアプローチと同じAsp.Net MVC でモデル検証を無効にする

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

プロジェクトが取得したモデル クラスが多すぎる (100 以上) ため、それぞれを手動で登録できません。

モデルの検証を完全にオフにする簡単な方法 (おそらく .config のキー) はありますか?

4

4 に答える 4

8

これが機能するかどうかはわかりませんが、これを試しましたか(ブートストラップコードまたはglobal.asax)

ModelValidatorProviders.Providers.Clear();
于 2012-10-29T13:29:28.280 に答える
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 を使用して View の実装を Model の実装から切り離すことをお勧めします。たとえば、次のようになります。

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; }
}

コントローラーのアクションは次のようになります:-

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);
}

StepOne ビューは次のようになります。

@model StepOneModel
@using (html.BeginForm()) {
   @html.EditorFor(x => x.Foo);
}

StepTwo ビューは次のようになります。

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

モデルの検証を単にオフにする場合と比べて、主な利点は、現在のステップの検証要件を ViewModel に設定できることです。ステップ 2 に進む前に、ステップ 1 のすべての値が有効であることを確認できます。

  • より RESTful なアプローチが必要な場合 (データがウィザード スタイルのビューから来ていることをコントローラーが気にしない場合)、別の一般的な解決策は、各ステップを <div> クライアント側でラップし、javascript を使用して非表示/表示することです。ユーザーが進行するにつれてそれらを。

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

于 2012-10-29T14:08:05.193 に答える
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());

または、&& t.Namespace == "Your.Name.Space"パーツを削除して、アセンブリ内のすべてのクラスを NonValidatingModelBinder に追加します。

追加することを忘れないでくださいusing System.Linq;

于 2012-10-29T13:27:08.037 に答える