2012-04-07 13 views
0

私はコードの最初のデータベースを持っています。表には、問題は私が作成しようとするたびにgetメソッドコードの最初の1対1リレーションシップとMVCの作成問題

public ActionResult Create() 
    { 
     ViewBag.Id = new SelectList(db.Deadline, "Id", "Id"); 
     var Year = new Year(db.Year.OrderByDescending(x => x.Value).FirstOrDefault().Value + 1); 
     Year.Deadline = new Deadline(Year); 
     return View(Year); 
    } 

とPOSTメソッド

[HttpPost] 
    public ActionResult Create(Year year) 
    { 
     if (ModelState.IsValid) 
     { 
      if (db.Year.Select(x => x.Value).Contains(year.Value)) 
      { 
       ModelState.AddModelError("AlreadyExists", "That year has already been added to the database, please edit instead"); 
       return View(year); 
      } 
      db.Year.Add(year); 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 

     return View(year); 
    } 

を作成した年のためのコントローラを持って

public class Deadline 
{ 
    public Deadline() { } 
    public Deadline(Year year) 
    { 
     this.Year = year; 
    } 

    public Guid Id { get; set; } 

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

    [Required] 
    [DataType(DataType.Date)] 
    [DataAnnotationsExtensions.Date] 
    public DateTime From { get; set; } 

    [Required] 
    [DataType(DataType.Date)] 
    [DataAnnotationsExtensions.Date] 
    public DateTime To { get; set; } 
} 

public class Year 
{ 
    public Year(Int32 value) { this.Value = value; } 

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public Guid Id { get; set; } 

    [Required] 
    [Display(Name="Year")] 
    [DataAnnotationsExtensions.Year]   
    public Int32 Value { get; set; } 

    public virtual Deadline Deadline { get; set; } 
} 

ある私を引き起こし新しい年(年の値と締め切りの日付を設定しています)、それはポストに戻って、モデル状態は無効です。

[年]フィールドは必須です。

私がチェックしたとPOSTメソッドでyear.Deadline.Yearは、それがさえ

を入れ、狂気私を運転している理由(とどのように私はこの問題を解決することができます)私が知りたいことはあり、実際にnullであります
@{ Model.Deadline.Year = Model; } 

は表示されませんでした。

編集、次の作品

using (ProjectSelectionAndAllocation.Models.DatabaseContext Context = new Models.DatabaseContext()) 
    { 
     var h = new Models.Year(1001); 
     h.Deadline = new Models.Deadline(h); 
     Context.Year.Add(h); 
     Context.SaveChanges(); 
    } 
+0

変更前に表示されていた場合は、私がタグ付けしていた間に何らかの理由でミスマッチがありました。 – Manatherin

+0

Model.Deadline.Year =モデルが有効ではないようです。モデルは一年ではないですね。ビューの元のコードは何ですか? – CodeRedick

+0

モデルは年、コントローラーは年とその@model Namespace.Models.Year、元のコードを変更していないのは、ビューを設定しているかどうかを確認するための行です。 – Manatherin

答えて

1

私は問題に関して2つの基本的な理論を持っていますが、とにかく実装すべき1つの解決策があります。

だから私は解決策から始めます:ViewModelを使用してください。これは、ビューが表示したいフィールドだけを含む小さくてフラットな軽量クラスです。データレイヤーと同じであってはなりません。ビューはちょうどレンダリングする必要があり、ViewModelは表示されるデータだけを含む必要があります。

あなたは(AutoMapperは、このためにかなり人気がある。)のViewModelにあなたの実際のオブジェクトからのデータをマップします今

を、なぜこれが役立つのだろうか?あなたの問題に関する私の理論は以下の通りです。

1)モデルバインダーは仮想プロパティを好まないかもしれません。 MVCの関数にフォームを返すときは、実行されるコードがほとんどなく、フォームのすべての値をフィールドにマップしようとします。このモデルのバインダーは、仮想フィールドを把握できない場合や、自動的にマップされない理由があるかもしれません。いずれにしても、ViewModelはこれを通常のパブリックプロパティに置き換えます。

2)もう一つの可能​​性は、循環参照(年 - >期限 - >年)があり、モデルバインダーがそれをうまく扱えないということです。ただし、ViewModelコンセプトではそれを取り除くだけで、ViewModelにYearフィールドが追加されます。ここで

0

は、私は私のモデルがビューに正しく配線されていなかったとき、これが私に起こる持っていました。このようなことは、モデルバインダーがポストアクションでモデルを実現するのを妨げます。確認するべきことの1つは、あなたのビューで良いasp.net mvc命名規則を使用していることを確認することです。

0

は、私が考えていたものであるあなたは何が起こっているか分からないとき、それはしばしば...もっと詳細をポストに
参照便利な証明だ:https://stackoverflow.com/a/10037334/417747
を...

同様の場合、バインディングが期待どおりに機能しない場合は、デバッグに役立ちます。カスタムバインダーを作成すると、デバッグに役立ちます。等も彼らとの問題が
(あなたはいくつかのオプションを試し、テストする必要があると思い、あるかもしれないかどうかを確認 -

public class YearClassBinder : DefaultModelBinder 
{ 
    //public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    //{ 
    //} 
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) 
    { 
     var model = (Year)base.CreateModel(controllerContext, bindingContext, modelType); 

     // ...you change, inspect set etc. 

     return model; 
    } 
} 

...これはあなたの「合格」の値を調整し、カスタムバインドへの道であります方が良いでしょうBindModel、依存)

(あなたがそのリンク内の詳細を持っている)

は、それは正確な答えではないですが、右のトラックにほとんどの時間をあなたを取得します。

願っています。

編集:ちょうどを追加する場合は、この同じ方法を使用して、必要に応じて年のインスタンスを手動で調整し、1つのポスター(循環参照など)のような問題の場合に作成できます。

関連する問題