2017-03-07 57 views
1

Professional ASP.NET MVC 1.0のNerdDinnerの例(Visual Studio 2015に付属しているASP.NET MVCのバージョンを使用しています)に従っています。いくつかの小さな問題を修正するが、これは私を得た。ModelStateエラーがモデルの変更後に表示されない

Dinnerという名前のモデルがあります。このモデルは、Create()という名前のアクションのビューに渡されます。作成に対応するビューは、基本的にいくつかの情報を要求するフォームであり、送信されると、ページにエラーがある場合に表示されます。エラーは、ModelStateオブジェクトを介してビューに伝達されます。

public ActionResult Create() 
    { 
     Dinner dinner = new Dinner(); 
     return View(dinner); 
    } 

    [HttpPost] 
    public ActionResult Create(Dinner d) 
    { 
     TryUpdateModel(d); 
     if (d.isValid) 
     { 
      ... 
     } 
     else 
     { 
      foreach (var violation in d.GetRuleViolations()) 
       ModelState.AddModelError(violation.PropertyName, violation.ErrorMessage); 
      return View(d); 
     } 
    } 

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

@model NerdDinner.Models.Dinner 

... 

      @Html.ValidationMessageFor(Model => Model.Title, "", new { @class = "text-danger" }) 

... 

これは、DinnerFormViewModelという新しいモデルを作成して、追加のオブジェクトを作成ビューに渡すまでうまくいきました。

public class DinnerFormViewModel 
{ 
    public Dinner Dinner 
    { 
     get; 
     private set; 
    } 

    public DinnerFormViewModel() : this(new Dinner()) { } 

    public DinnerFormViewModel(Dinner d) 
    { 
     Dinner = d; 
    } 

    ... stuff ... 
} 

対応するビューに正しいモデルを渡していることを確認するためにCreate()メソッドを更新しました。

public ActionResult Create() 
    { 
     Dinner dinner = new Dinner(); 
     return View(new DinnerFormViewModel(dinner)); // Updated line. 
    } 

    [HttpPost] 
    public ActionResult Create(DinnerFormViewModel d) // Updated line. 
    { 
     TryUpdateModel(d); 
     if (d.Dinner.isValid) // Updated line. 
     { 
      ... 
     } 
     else 
     { 
      foreach (var violation in d.Dinner.GetRuleViolations()) // Updated line. 
       ModelState.AddModelError(violation.PropertyName, violation.ErrorMessage); 
      return View(new DinnerFormViewModel(d.Dinner)); // Updated line. 
     } 
    } 

また、ビューを更新しました。

@model NerdDinner.Models.DinnerFormViewModel 

... 

      @Html.ValidationMessageFor(Model => Model.Dinner.Title, "", new { @class = "text-danger" }) 

... 

それは(有効な形式のデータが正しく保存されている)必要がありますように、ページの機能が、無効な情報が送信されたときにエラーがもはやページに表示されていません。ビューファイルで、私はModelStateに格納されているエラーをチェックし、それらはすべてそこにありました。 ModelStateとフォームフィールドの間には切断があるようです。私は問題がModelState.AddModelError()メソッドに提供しているプロパティ名だと思っていますが、それについてはわかりません。どんな助けもありがとうございます。

答えて

1

最初に、モデル内にクラスインスタンスプロパティがある場合、nullの場合、検証はそのプロパティで実行されません。次に、クラスインスタンスのプロパティにプライベートセッターがあるため、モデルバインダーは実際に何かに設定することができず、常にnullになります。

長短ですが、問題はプライベートセッターです。

+0

最初にDinnerFormViewModelのコンストラクタを追加しておく必要があります。 DinnerFormViewModeクラスでは、インスタンス化されるたびにDinnerオブジェクトが渡されるか、新しいインスタンスが作成されるかどうかを確認しています。実際、DinnerFormViewModel(Dinner d)では、dがnullかどうかはチェックしていませんが、常にnull以外のDinnerオブジェクトを渡すと思います。私はまだそれが起こるかどうかを確認するためのチェックを追加するつもりです。だから、プライベートセッターは問題ではないはずです(私はそれを公にしようとしましたが、うまくいきませんでした)。 – puck

+0

それはまだ1つの問題です。 modelbinderはパラメータのないコンストラクタのみを使用するため、公開されている投稿データでプロパティを設定することができます。 –

関連する問題