2016-05-27 7 views
0

シナリオ:ナビゲーションプロパティのAsp.net MVCの検証エラーを克服する方法

私はEntity FrameworkをしてAsp.Net MVCプロジェクトを実施しています。

class Employee{ 
    public int Id{get;set;} 
    [Required] 
    public string Name{get;set;} 
} 

class Department{ 
    public int Id{get;set;} 
    public string DepartmentName{get; set;} 
    public virtual Employee manager{get; set;} 
} 

ここで、データベースの従業員のリストからマネージャーを持つ新しい部門を作成する必要があります。このため、ビューとコントローラアクションは次のとおりです。

@Html.EditorFor(model => model.DepartmentName) 
@Html.DropDownListFor(model => model.manager.Id, new SelectList(ViewBag.Managers, "Id", "Name")) 


public class DepartmentController: Controller{ 
    private MyDatabaseContext db = new MyDatabaseContext(); 

    [HttpGet] 
    public ActionResult Create(){ 
     ViewBag.Managers = db.Employees.ToList(); 
     return View(); 
    } 

    [HttpPost] 
    public ActionResult Create(Department d){ 
     if(ModelState.IsValid){ 
      d.manager = db.Employees.Find(d.manager.Id); 
      db.Departments.Add(d); 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     else{ 
     //error response. 
     //Error encounters as d.manager.Name field would be null. 
     } 
    } 
} 

問題:プログラム上で実行している場合

ModelState.IsValidは常にfalseあるとして、私は、新しいDepartmentのオブジェクトを作成することはできません。これは、ナビゲーションプロパティmanagerにフィールドNameがあり、フォームを送信するときにnullとなるためです。 Nameが必須フィールドであるため、これはエラーとしてリストされます。

質問:

どのように私は、ナビゲーションプロパティの分野でnullに起因するエラーを克服することができますか?または、このエラーを取り除くためにこのコードを実装する他の方法がありますか?

注:

私はDepartmentオブジェクトを作成するための単なる便利ViewModel異なるを作成しないことに注意してください。私はDRY原則に従うことを好むでしょう。 また、私はEmployeesテーブルの外部キーとなる別のフィールド(managerIdのようなもの)を作成したくありません。なぜなら、オブジェクト指向モデルに注意を払ったデータベースの関連付けは望んでいないからです。 department.managerId [Key]フィールドを渡すことによって、エンティティフレームワークからマネージャオブジェクトを読み取るのではなく、department.managerによってマネージャを取得するのが常によりクリーンです。

ありがとうございます。

+1

いつものように、ビューモデルを使用します(問題を解決する唯一の現実的な方法です)。 DRYプリンシパルを破ることはありません。すべてのビュー、特に編集用のビューは、独自のビューモデルを持つ必要があります。 [MVCのViewModelとは何ですか?](http://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc)も参照してください。また、そのビューモデルには、 'ViewBag'の使用を避け、強い型付けのバインディングを得るために、IEnumerable ManagerList'も含まれている必要があります。 –

+0

@StephenMueckeが説明した方法でViewModelを実装しました。このソリューションは正常に動作し、アーキテクチャとコードもきれいに見えます。しかし、私はまだ私の心に一つの質問があります。 Spring MVCでは、ナビゲーションプロパティの '@ Valid'アノテーションを入れて、フレームワークにナビゲーションプロパティの妥当性を検証させることができます。 '@ Valid'アノテーションを付けないと、フレームワークはバリデーションを実行せず、エラーも発生しません。あなたはAsp.Net MVCのそのような注釈/機能を知っていますか? –

答えて

2

Departmentオブジェクトの作成に役立つ別のViewModelを作成したくないことに注意してください。私はDRY原則に従うことを好むでしょう。

この場合のビューモデルの使用は、DRYの原則に違反しません。ビューモデルは、異なる概念(ビューに必要なデータ)を表します。これは、データベーステーブル(ドメインモデル)に必要なデータとはまったく異なるものです。ビューモデルとドメインモデルが、最初にそれらを実装するときに同じプロパティを持つ場合は、が完全に一致しますです。

DRYの原則は、同じコンセプトを複数の場所で繰り返しないようにすることです。

ビューモデルを使用することは、データアクセスレイヤの検証要件がUIレイヤの検証要件とは無関係に異なることを可能にするため、具体的には正しいアプローチです。 UIでドメインモデルを再利用することで、柔軟性が失われ、同じ問題が継続的に発生します。

+0

あなたの答えに強い点を作っていただきありがとうございます。私は現在、なぜViewModelsを使用するのが合理的であるのかを確信しています。 –

1

あなたは教室でこの

public int EmployeeId {get;set;} 

を必要としています。

+0

はい、このアプローチは、エラーを克服するために正常に動作します。しかし、モデル/エンティティを変更することなく、問題を解決する他の方法があるかどうかを把握しましょう。つまり、ドメインモデルの設計の観点からは、データベース関連のフィールドをモデルに追加するのは快適ではありません。私は、エンティティフレームワークがこれを世話することを好む。 –

関連する問題