2011-01-05 3 views
0

モデルバインダーを使用しているのは、私は心の中で、次の「ビジネスオブジェクト」でフォームを持っているとしましょう:ラウンドトリップビューデータ

public class MyObject 
{ 
    public string Name { get; set; } 
    public User OtherUser { get; set; } 
    public DateTime CreateDate { get; set; } 
    public DateTime? StartDate { get; set; } 
    public DateTime? EndDate { get; set; } 
} 

ユーザーがいずれかのフィールドにデータを入力すると私は彼らの反応を再入力することなく、脂肪指などを修正するために彼らが入力したものをラウンドトリップする必要があります。

私は往復DateTimeフィールドに「2011年2月31日」のような値が、私はこのようなビューモデルオブジェクト使用して終了することはできませんので:

public class MyObjectViewModel 
{ 
    public string Name { get; set; } 
    public string OtherUserName { get; set; } 
    public string CreateDate { get; set; } 
    public string StartDate { get; set; } 
    public string EndDate { get; set; } 
} 

を[OK]を、すべてが細かく、

public ActionResult Create(FormCollection form) 
{ 
    var model = new MyObjectViewModel(); 
    if (TryUpdateModel(model, form) && ModelState.IsValid) 
    { 
     // ... 
    } 

    return View(model); 
} 

私は、次の質問を持つ:ダンディ、私は次のパターンを使用している場合、これは裸のビジネス・オブジェクトと値の往復とまったく同じレンダリングするために取得することができます

  1. データをビューモデルからビジネスオブジェクトに取り込む最もクリーンな方法は何ですか? (つまり、上記の方法の残りの部分を記入してください)
  2. 変更を統合するために、オブジェクト間のフィールド名の重複を減らすことはできますか?
  3. 上記の例では、フィールドOtherUserNameは、Userオブジェクトに変換する必要があるstringです。誰の責任ですか?コントローラー? ViewModel?モデルバインダー?

答えて

-1

1)ビューがコントローラに「MyObject」タイプを渡すように、ビューを強く入力できます。 2)あなたが尋ねていることを理解していません 3)このフィールドをリンクIDの外部キーを含むIDにしてみませんか?

また、日時フィールドをビューに渡してそのまま左に戻す理由はありません。文字列として渡して変換する必要はありません。

PS - このチュートリアルをご覧になることをお勧めします。回答を明確にする必要があります。

http://www.asp.net/mvc/videos/what-is-aspnet-mvc-80-minute-technical-video-for-developers-building-nerddinner

+0

1)まず、私の意見が強く型付けされています。また、そうしなければ、データはラウンドトリップしないので、既存のデータベースオブジェクトをそのように更新することはできません。 3)データベース内のオブジェクトのIDにユーザータイプを設定したいのですか?私はそれがうまくいくとは思わない。 –

+0

1)次に、最もクリーンな方法は、コントローラにFormCollectionの代わりに "MyObject"タイプが必要であることを伝えることです。厳密に型指定されたビューを使用している場合、バインディングは簡単です。 3)いいえ、私は通常、JSON/AJAXを介してフレンドリーな名前を取得し、それをドロップダウンにバインドします。ユーザーはそれを選択できますが、IDはコントローラーに渡されます(これを行うにはJavaScriptのヘルプが必要です - 選択したIDを隠しモデルIDフィールドにバインドするビューで必要です)。 AutoMapper用の –

0

あなたの問題は、ビューモデルに無効​​なデータが含まれてできるようにすることで、ほとんどが原因です。あなたのデータクラスと同じような強い型をあなたのビューモデルに使用し、少しのJavaScriptの検証を追加し、 "Feb 31"はサーバーに決して行かないでしょう。型を解析することは、モデルバインダーの責任です。何もする必要はありません。コントローラのアクションは厳密に型指定されたモデルオブジェクトを渡すだけです。しかし、主な違いは、viewmodelにusernameという名前のフィールドがあり、データモデルにはフォームにない情報を持つユーザーオブジェクトが必要なことです。あなたのコントローラは、適切なユーザオブジェクトをフェッチ/作成し、それをデータクラスに追加する必要があります。

モデルが解析された後でもサーバー側で検証が行われますが、単純な文字列形式の問題ではなく、フィールドが一致しているかどうかを確認するなど、よりカスタムな作業になります。

は、重複を減らすために、私は別の質問にモデルの私のスタイルを掲載 - あなたがする必要はありません asp.mvc model design

2
  1. AutoMapper
  2. マッパー

例:

[HttpPut] 
public ActionResult Create(MyObjectViewModel viewModel) 
{ 
    if (!ModelState.IsValid) 
    { 
     // there are validation errors => redisplay the view 
     return View(viewModel); 
    } 
    var model = Mapper.Map<MyObjectViewModel, MyObject>(viewModel); 
    _repository.DoSomethingWithTheModel(model); 
    return RedirectToAction("Success") 
} 
+1

+100 #2を強化するために、重複を排除するために、最も強い動機ではありません。私は特定の点で重複を見つけるように見える - ViewModelsは、アプリケーションレイヤの境界を越えるものの1つで、そのような点である - 複雑さの正味の減少を有する。つまり、お互いを鏡映するいくつかのオブジェクトを持つと、複雑さが増します。しかし、その複雑さは比較的小さい。ビューとドメインの間の結合を減らすことは、やはり大きな効果をもたらします。 –

+0

興味深い... automapperは既存のオブジェクトのプロパティを更新しますか? –

+0

@John、AutoMapperはプロパティを同じ名前で自動的にマッピングします。異なる名前/規則がある場合は、それらを定義する必要があります。 –