2017-07-31 2 views
1

にモデルを渡すループに私は私のモデルのIEnumerableををループしています:MVC Html.HiddenForはバックコントローラ

@model IEnumerable<Testing.Models.ProductItem> 
@{ 
    ViewBag.Title = "Buy Products"; 
} 

<div class="row"> 
    @foreach (var product in Model) 
    { 
     using (Html.BeginForm()) 
     { 
      @Html.HiddenFor(Model => product) 
      ... More Controls and stuff... 
      <input type="submit" value="Add To Kart" class="btn btn-info"> 

     } 

    } 
</div> 

との私は戻って私のコントローラへの私のモデルの選択したインスタンスを渡したい提出します:

[HttpPost] 
    public ActionResult Index(ProductItem product) 
    { 
     ... Do Stuff ... 
     return View(); 
    } 

は、しかし、私はいくつかのことを試してみましたが、常にnullをコントローラに渡さなっているようだ...誰かが正しい方向に私を指す助けてください可能性がありますか?

に投稿
@model IEnumerable<Testing.Models.ProductItem> 
@{ 
    ViewBag.Title = "Buy Products"; 
} 

<div class="row"> 
    @foreach (var product in Model) 
    { 
     using (Html.BeginForm()) 
     { 
      @Html.HiddenFor(Model => product.ID) 
      @Html.TextBox("qty", "1", htmlAttributes: new { @style = "width: 30px;" }) 

      ... More Controls and stuff... 

      <input type="submit" value="Add To Kart" class="btn btn-info"> 

     } 

    } 
</div> 

:私は次のことを試してみました - 私はIDからコントローラ内にこれを取得することができますように私は実際にはいけない

EDIT

は、フルモデルインスタンスに必要コントローラ:

[HttpPost] 
public ActionResult Index([Bind(Include = "ID")] int? ID, [Bind(Include = "qty")] int? qty) 
{ 
    return null; 
} 

テキストボックスは、入力されたモデルの一部ではありません。この値は、アクティベーションしかし、私はまだHiddenForコントロールのIDのnullを取得しています。これはコントロールの命名と関係がありますか?私はHiddenForコントロールに名前を追加することはできないようです。

私はこれが元の質問に異なる光を当てることを知っていますが、あなたがまだ助けてくれることを望んでいます。

BeginFormがループ内にあることに注意してください - リストの各項目を作成しています...これには簡単な代替手段はありますか(まだ何も試していないことに注意してください)。

+0

コードには複数の問題があります。まず、複雑なオブジェクトをフォームコントロールにバインドすることはできません(モデルの場合は、それぞれのプロパティをバインドする必要があります)。コレクション内の各アイテムのフォームは意味をなさない - 一度に1つのフォームのみを送信することができ、いずれの場合でもモデルに関係のない入力を生成する –

+0

フォームコントロールを単一のフォームで生成するか'for'ループまたは' EditorTemplate'を作成し、それをすべて1つのアクションで実行します([この回答](http://stackoverflow.com/questions/30094047/html-table-to-ado-net-datatable/30094943#30094943 ))、または一度に1つのアイテムのみを更新したい場合は、ajaxを使用するか、リンク先にアイテムを編集するためのページが表示されます –

+0

ありがとうございました...私はちょっと質問を更新しました完全なモデルの代わりにIDを渡します。あなたが見て、あなたの考えを私に知らせることができたら、今は素晴らしいだろう。 – CJH

答えて

2

複雑なタイプのHiddenForを使用しようとしているようですが、それは動作しません。 ProductIdのようなProductItemのようなプロパティを使う必要があります。これはおそらくintまたはGuidになります。

単純なフィールドへの複雑なバインディングをクリアしたので、あなたの名前がproduct.idに設定されていることがわかります。そのため、コントローラでは常にnullです。あなたは、のために隠されたとname属性をオーバーライドすることはできませんので、あなたがにあなたのコードを変更することをお勧めします:

代わりにモデル=> product.Idの
@foreach (var product in Model) 
{ 
    using (Html.BeginForm()) 
    { 
     @Html.Hidden("ID", product.ID) 
     @Html.TextBox("qty", "1", htmlAttributes: new { @style = "width: 30px;" }) 

     <input type="submit" value = "Add To Kart" class="btn btn-info"> 
    } 

} 
+0

ありがとうcodepros ...そのことを踏まえて、フルモデルの代わりにIDを渡すために少し質問を更新しました。あなたが見て、あなたの考えを私に知らせることができたら、今は素晴らしいだろう。 – CJH

+0

Heya @CJH、HiddenForは自動的に名前とIDを設定します。 IDを上書きすることはできますが、簡単に名前を上書きすることはできません。したがって、Html.Hiddenを使用したいと思う機能を得るためには、例えば: (Html.BeginForm())を使用してください。 { Html.Hidden( "ID"、product.ID) Html。 TextBox( "qty"、 "1"、htmlAttributes:new {style = "width:30px; } – coderpros

-1

、試すのp => product.Id

@model IEnumerable<Testing.Models.ProductItem> 
    @{ 
     ViewBag.Title = "Buy Products"; 
    } 

    <div class="row"> 
    using (Html.BeginForm()) 
    { 
     @foreach (var product in Model) 
     { 
      @Html.HiddenFor(p => product.ID) 
      @Html.TextBox("qty", "1", htmlAttributes: new { @style = "width: 
      30px;" }) 

      ... More Controls and stuff...   

     } 
     <input type="submit" value="Add To Kart" class="btn btn-info"> 
    } 
    </div> 
正確に隠されたIDとコントローラのアクションへのテキストボックスの内容を提出

@model List<ShoppingKartTest.Models.ProductItem> 
@{ 
    ViewBag.Title = "Buy Products"; 
} 



@foreach (var item in Model) 
{ 
    using (Html.BeginForm()) 
    { 

     <input type="hidden" value="@item.ID" name="ID" /> 
     @Html.TextBox("qty", "1", new { @style = "width: 30px;" }) 


     <input type="submit" value="Add To Kart" class="btn btn-info"> 
    } 
} 

+0

それはまだ彼のコントローラーが(現在どのように書き込まれているかに基づいて)値を取得しないことを意味するproduct.IDの名前で隠れた入力をレンダリングします。 – coderpros

0

は、私は次のように(正しくまたは誤って)私の目的の機能に到着するために管理している

[HttpPost] 
public ActionResult Index(int ID, int qty) 
{ 
    //... Do stuff with parameters... 
    return View(); 
} 

私はこれに関するコメントを聞くことに興味があります。私は、ループの中で私のBeginFormを持つべきではないということを私が上で言われたことを知っています...しかし、それは私のために働くだけです。

+0

このコード自体には何も「間違っている」ことはありません。それは、私が今朝あなたに与えたコードとほぼ同じです。 あなたのアプローチはうまくいかないと主張しているわけではありませんが、それは醜く現代のベストプラクティスに反する/スケーラビリティがないということです。あなたのコードは、不必要に多くのフォームのオープンタグとクローズタグをあなたのページを膨らませてレンダリングしています。 より正確で現代的なアプローチは、単一のHtml.BeginFormまたはAjax.BeginFormを持ち、コントローラにAJAXを介して「カートに追加」のクリックを受け入れるようにすることです。 – coderpros

+0

フィードバックcodeprosをありがとう...私はそれを感謝します。私の現在のプロジェクトは、決して生産環境を見るつもりはなく、機能的な例として純粋に使用されるので、私はちょうどそれを取り除くかもしれません...今度は... – CJH

+1

このコードでは悪いことがたくさんあります。モデルへの双方向バインディングではなく、検証を取得せず、ビューを返さなければならない場合は正しく動作しません。なぜあなたはすべての利益を無効にするコードを書くつもりなら、MVCを使用してください。 –

関連する問題