2011-07-14 15 views
3

別のクラスを指定する必要があるクラスがありますが、MVC ModelStateバリデータでセカンダリモデルが有効かどうかを確認する必要はありません。これは可能ですか?「サブモデル」を検証せずにMVC-3モデルを検証できますか?

public class WidgetType 
{ 
    public long Id { get; private set; } 

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

    ... 
} 

public class Widget 
{ 
    public long Id { get; private set; } 

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

    [Required] 
    public WidgetType WidgetType { get; set; } 

    ... 
} 

私は彼らが私はこのようなビューへ/から渡しているWidgetViewModelクラスにカプセル化されています:

私のエンティティは次のようになり:ここ

は簡単な概要です

... 
@Html.DropDownListFor(m => m.Widget.WidgetType.Id, new SelectList(new EquipmentViewModel().EquipmentTypes, "Id", "Name")) 
... 
012:
public class WidgetViewModel 
{ 
    public Widget Widget { get; set; } 

    public ICollection<WidgetType> WidgetTypes 
    { 
     get 
     { 
      return _repository.GetWidgets(); 
     } 
    } 

    ... 
} 

私の見解は次のようになります

これらのすべては、検証以外は機能します。 "Widget.WidgetType.Name"が必要なため、ModelState.IsValidは常に偽です。 WidgetTypeを選択する必要がありますが、ModelStateを「Widget.WidgetType.Id」よりも深く検証することは望ましくありません(その外字キーにはWidgetが必要です)。

これを行うより良い方法はありますか?再帰的にプロパティを調べることなく検証する方法があるはずですが、見つけられません。私は何が欠けています...?

+1

を与えます検証。 http://blog.stevensanderson.com/2010/02/19/partial-validation-in-aspnet-mvc-2/ – bmosh

+0

@bmoshそれは有望そうです。オフィスでそれをチェックします。 – Farray

+0

@bmosh 'ActionFilterAttribute'を作成することで、まさに私が望むことができました。あなたが答えを投稿するなら、私はそれを受け入れるでしょう。ありがとう。 – Farray

答えて

3

あなたのビューに必要なものがすべてWidgetIDであれば、ウィジェット全体をWidgetViewModelに含める必要はありません。 WidgetIDというプロパティがあります。ビューモデルクラスは、ビューに必要なデータのみを持つ必要があります。

フォームを送信するときに呼び出されるコントローラアクションメソッドでは、必要に応じてWidgetIDを使用してデータベースからWidgetオブジェクトをフェッチできます。

+0

WidgetTypeは、他のビューでは重要です.WidgetTypeは、設定可能な編集ページでは表示されません。異なるビューの複数のビューモデルを用意する必要がありますか? – Farray

+0

多くの場合、それぞれのビューに対してviewmodelクラスが用意されています。 – HitLikeAHammer

+0

この質問に対する選択された答えをチェックしてください:http://stackoverflow.com/questions/664205/viewmodel-best-practices – HitLikeAHammer

4
public class WidgetViewModel 
{  
    [Required] 
    public string Name { get; set; } 

    [Required] 
    public WidgetType WidgetTypeId { get; set; } 

    public SelectList WidgetTypes 
    { 
     get 
     { 
      //This should be popuplated in your controller or factory not in the view model 
      retun new SelectList{ _repository.GetWidgets(),"Id","Name"); 

     } 
    } 
} 
あなたのビューで

@Html.DropDownListFor(m => m.WidgetTypeId, Model.WidgetTypes) 

そして、あなたのコントローラで

public ActionResult Create(WidgetViewModel model) 
{ 
    Widget widget = new Widget{ 
     Name = model.Name, 
     WidgetType = yourManager.GetWidgetTypeByID(model.WigetTypeId); 
    }; 

    yourManager.Create(widget); 

    //... 
} 
+0

これはかなり意味がありますが、それでも検証のために 'ModelState'を使用することは可能ですか? – Farray

+0

@Farray:はいModelStateは、ウィジェットクラスではなく、あなたのviewmodelクラスに基づいてデータを検証するために使用できます – Gregoire

+0

私はbmoshのコメントごとにカスタム 'ActionFilterAttribute'を実装しましたが、私はViewModel&あなたのアドバイスに従って表示してください。助けてくれてありがとう。 – Farray