2011-10-20 5 views
2

すべては、モデルバインディングがIEnumerablesおよびエディタテンプレートとどのように機能するかについて私の混乱を解消してください。ASP.Net MVC3モデルバインディングIEnumerable <T>エディタテンプレート

私はこれがある

@model IEnumerable<MvcWebsite.Models.Approve> 
<table> 
    <tr> 
     <th> 
      Name 
     </th> 
    </tr> 
    @Html.EditorForModel() 
</table> 

モデル、Approve.cs

public class Approve 
{ 
    public string Name { get;set;} 
    public string Role { get; set; } 
} 

、エディタテンプレート

@model MvcWebsite.Models.Approve 

@using (Html.BeginForm("Approve", "Registration", FormMethod.Post)) 
{ 
<tr> 
    <td> 
     @Html.HiddenFor(m => m.Name) 
     @Html.EditorFor(m => m.Role) 
    </td> 
    <td> 
     <input type="submit" value="Approve" class="submit-button" />    
    </td> 
</tr> 

}

Approve.cshtml

、ビューを持っていますすべての良いと良い。次の出力を表示します。

 <input name="[0].Name" type="hidden" value="" /> 
     .... 

ただし、私のコントローラでは、Model(バインディング)の値を返すように見えません。

[HttpPost] 
public ActionResult Approve(Approve approveModel) 
{ 
    .... approveModel has all default values 
} 

私がここで間違っていることに誰かが光を当てることができますか?私はコードを省略し、私はモデルから他のEditorForとHiddenForフィールドを使ってエディタテンプレートを使用しています...

編集:私は基本的にテーブルレイアウトを持っています、それぞれユーザー名、 (ユーザーまたは管理者)、次に承認ボタンを押して自分のコントローラーに送信します。そのため、私は1つのApproveオブジェクトだけを返す必要があります。私はIEnumerable全体を私のコントローラに返すことができますが、そうすると、承認ボタン(送信)をクリックしたアイテムがどのアイテムであるかをどのようにして知ることができますか?

EDIT: は、だから私は、私は私の全体のビューApprove.cshtml

@model IEnumerable<MvcWebsite.Models.Approve> 
@using (Html.BeginForm("Approve", "Program", FormMethod.Post)) 
{ 
<table> 
    <tr> 
     <th> 
      Name 
     </th> 
    </tr> 
    @Html.EditorForModel() 
</table> 
} 

を囲む単一のフォームを持っているようにコードを変更し、そして今、私は」

[HttpPost] 
public ActionResult Approve(IEnumerable<Approve> approvals) 
{ 
    // ??????????????????????? 
} 

にコントローラを変更しました私はApprove forをクリックした行を知る方法についてまだ明確ではありません。私はこのタスクを達成する他の方法があることを知っている(承認するためのチェックボックスを作成し、チェックされたものを承認するなど)しかし、私はボタンをクリックして、情報を他の行に追加します。 IEnumerableを自分のモデル(AllApprovals)内にラップして、親モデル(SelectedIndexなど)にヘルパープロパティを追加する方が良いでしょうか?それが取るアプローチならば、承認ボタンをクリックした後、どのようにSelectedIndexを設定するのですか?それはまだjqueryの魔法か、これを達成するための正しいMVCの方法ですか? Jqueryの魔法は私にとって非常にハックされているようですか?

編集:Brianの応答に基づいて、ここに私の最後です。それでもかなり気分が悪いですが、うまくいきます!

ビュー

@model IEnumerable<MvcWebsite.Models.Approve> 
<table> 
    <tr> 
     <th> 
      Name 
     </th> 
    </tr> 
    @Html.EditorForModel() 
</table> 

エディタテンプレート

@using (Html.BeginForm("Approve", "Registration", FormMethod.Post)) 
{ 
<tr> 
    <td> 
     @Html.HiddenFor(m => m.Name) 
     @Html.EditorFor(m => m.Role) 
    </td> 
    <td> 
     <input type="submit" value="Approve" class="submit-button" />    
    </td> 
</tr> 
} 

あなたは、単一の承認クラスに結合しているコントローラ

[HttpPost] 
public ActionResult Approve([Bind(Prefix="approval")]Approve approval) { 
    // WORKS! 
} 

答えて

1

一度に1つずつ変更するだけなので、値が変更されたコントローラを調べたり、変更されたプロパティを追加したり、javascriptで設定したりするよりも簡単です。私は投稿フォームのどの伝えることができますどのように私はIEnumerableを に結合するか

@Html.HiddenFor(m => m.Name) 
@Html.EditorFor(m => m.Role) 
+1

これは正解とマークしました。しかし、これを行う "正しい"方法ですか?あなたがビューでForeachを使用している場合、あなたは何か間違っていると私は別の場所で読んでいます。また、私はコントローラのバインディングプレフィックスを使用してこれを動作させる必要がありました[Bind(Prefix = "approval")] – firetoast

+1

これはあなたのために正しいと思われます。あなたは、あなたが構築しているシステムについてのより多くの経験と知識を持って、今から1年後にコードを見て、「私は考えていました」と考えます。それが「正しい」かどうかを心配するのは良いことですが、物事を終わらせることも良いことです。すべてのことと同様に、節度が鍵です。 –

+0

この質問には間違っていますが、無効なマークアップが生成されるため上記は正しくありません。​​(またはthなど)以外の表のどこにでもフォーム要素を置くことは無効です。それは "仕事"かもしれないが、それはハッキーです。 – smdrager

0

、あなたがIEnumerable<Approve>

+0

からApproveエディタテンプレートは、フォローアップする

@model IEnumerable<MvcWebsite.Models.Approve> <table> <tr> <th colspan=2> Name </th> </tr> @foreach(var user in Model){ @using (Html.BeginForm("Approve", "Registration", FormMethod.Post)) { <tr> <td> @Html.EditorFor(m => user) </td> <td> <input type="submit" value="Approve" class="submit-button" /> </td> </tr> } } </table> 

変化に

変更Approve.cshtml?私は本質的に各承認(EditorTemplate)をそれ自身のフォームでラップしています。そのフォームの中に私は値を入力している(UserまたはAdmin)EditorForフィールドを持っていて、それぞれの行をそれ自身のApproveモデルとしてコントローラーに送り返します。私はあなたがやろうとしていることをする良い方法があると思っています。 – firetoast

+0

行ごとに新しいフォームは必要ありません。idという承認モデルでプロパティを作成し、@ Html.Hiddenを使用してレンダリングします。このようにして、変更されたモデルと新しい値との間のマッピングを試すことができます –

0

マーティンに特異的に結合する必要があります私はただいくつかの情報を追加したいだけです。 [0]を使ってレンダリングされたHTMLは、モデルバインダーが見る特別な構文で、オブジェクトの場合はリストを扱っていると仮定します。アクションメソッドには1つのApproveクラスがあり、キストではないので、この問題が発生しています。

関連する問題