2011-07-09 11 views
1

デフォルトのモデルバインディングハンドルリストを作成するにはどうすればよいですか?リストへのモデルバインディング

のは、私がShoppingCartItemリストを持っているのShoppingCartクラスを、持っているとしましょう:

@ModelType VAVTag.LuckyDraw.ShoppingCart 

@Code 
    Layout = Nothing 
End Code 
<!DOCTYPE html> 
<html> 
<head runat="server"> 
    <title>Index</title> 
</head> 
<body> 
    @Using Html.BeginForm() 
    @<fieldset> 
     <legend>ShoppingCart</legend> 
     @Html.TextBoxFor(Function(m) m.CouponCode) 
     <hr /> 
     @Html.EditorFor(Function(m) m.Items) 

     <p> 
     <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 
    End Using 
</body> 
</html> 

Public Class ShoppingCart 
    Public Property CouponCode As String 
    Public Property Items As New List(Of ShoppingCartItem) 
End Class 

Public Class ShoppingCartItem 
    Public Property Title As String 
    Public Property Count As Integer 
End Class 

私の見解では、この(this、およびthisからのアドバイスどおり、ブログ投稿)のように見えます

アイテムはEditorTemplateを使用してレンダリングされます(Darinありがとう):

@ModelType ShoppingCartItem 
@Html.EditorFor(Function(m) m.Title) 
@Html.EditorFor(Function(m) m.Count) 
<br /> 

私のコントローラでは、いくつかのランダムなデータを挿入しています。このビューは、3つのアイテムを使ってショッピングカートをきれいにレンダリングします。

Public Class ShoppingCartController 
    Inherits System.Web.Mvc.Controller 

    Function Index() As ActionResult 
    Dim model As New ShoppingCart 
    model.Items.Add(New ShoppingCartItem With {.Count = 1, .Title = "Item A"}) 
    model.Items.Add(New ShoppingCartItem With {.Count = 17, .Title = "Item B"}) 
    model.Items.Add(New ShoppingCartItem With {.Count = 100, .Title = "Item C"}) 

    Return View(model) 
    End Function 

    <HttpPost()> 
    Function Index(model As ShoppingCart) As ActionResult 
    Return View(model) ' model is empty! 
    End Function 
End Class 

ただし、私がページを送信すると、値は取得されず、[クーポンコード]フィールドも表示されません。モデルオブジェクトは空です。何がありますか?

最終的に私の目標は、JavaScriptを使用してクライアントのアイテムを追加/削除してから、モデルバインダーにページの送信時に自動的に変更を反映させることです。

更新:モデルプロパティ宣言のPropertyキーワードが欠落していました。それは遅すぎる、と私はいくつかの睡眠を取得する必要があります。 :)

答えて

2

デフォルトのモデルバインディングハンドルのリストを作成するにはどうすればよいですか?

デフォルトのモデルバインダーalready handles lists and dictionariesはまったく問題ありません。

エディタテンプレートを使用してください。たとえば、次のように

ビューモデル:

public class ShoppingCartItem 
{ 
    public string Title { get; set; } 
    public int Count { get; set; } 
} 

public class ShoppingCart 
{ 
    public string CouponCode { get; set; } 
    public List<ShoppingCartItem> Items { get; set; } 
} 

コントローラー:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var model = new ShoppingCart 
     { 
      Items = new[] 
      { 
       new ShoppingCartItem { Count = 1, Title = "Item A" }, 
       new ShoppingCartItem { Count = 17, Title = "Item B" }, 
       new ShoppingCartItem { Count = 100, Title = "Item C" }, 
      }.ToList() 
     }; 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult Index(ShoppingCart model) 
    { 
     return View(model); 
    } 
} 

ビュー:

@model ShoppingCart 
@{ 
    Layout = null; 
} 
<!DOCTYPE html> 
<html> 
<head> 
    <title>Index</title> 
</head> 
<body> 
    @using (Html.BeginForm()) 
    { 
     <fieldset>   
      <legend>ShoppingCart</legend> 
      @Html.TextBoxFor(x => x.CouponCode) 
      <hr/> 
      @Html.EditorFor(x => x.Items) 
     </fieldset> 
     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    } 
</body> 
</html> 

と各項目のためにレンダリングされます最終的には、エディタのテンプレート(~/Views/Home/EditorTemplates/ShoppingCartItem.cshtmlItemsコレクションの一覧:

@model ShoppingCartItem 
@Html.EditorFor(x => x.Title) 
@Html.EditorFor(x => x.Count) 
+0

うん、それは私がリンクしているブログポストです。しかし、それは私のために働いていない、と私は理由を把握することはできません。 Scottsの例では、ビューモデル自体はコレクションですが、私のシナリオではリストはモデルのプロパティの1つです。 –

+0

@ Jakob Gadeでは、ビューに醜いループを書き、入力フィールド名を手動で生成する代わりに、エディタテンプレートを使用する必要があります。私はあなたの例を説明するために私の答えを更新しました。これがどれくらい簡単か見てください。ループや醜い意見を書いたり、フィールド名を心配する必要はありません。すべてが慣例によってうまく機能します。申し訳ありませんが、私のVB.NETは非常に錆びていますが、翻訳するのは簡単なことです。 –

+0

ありがとう、優秀な例、私はそれを試してみましょう。 –

関連する問題