2017-09-10 10 views
1

ASP .NET MVCを初めて使用しています。私の問題は - コントローラの処理できるようにアイテムのコレクションを「POST」したいです。 私のモデルはのコレクションです - 私のコントローラは、次のように定義されてASP.NET MVC-5でチェックボックスの選択項目のリストが常にnullとして投稿される理由

public class CheckedRentalProperty 
{ 
    public bool IsSelected { get; set; } 
    public int Id { get; set; } 
    public String Address { get; set; } 
} 

-

public class RentalPropertiesController : Controller 
{ 
    public ActionResult Index() 
    { 
     List<CheckedRentalProperty> checkHsList = new List<CheckedRentalProperty>(); 
     // Fill the list 
     return View(checkHsList); 
    } 

    [HttpPost] 
    public ActionResult Save(IEnumerable<CheckedRentalProperty> checkHsList) 
    { 
     // why checkHsList is coming as null ?? 
    } 
} 

そしてビューは、このようなものです -

@model IEnumerable<XXX.Models.CheckedRentalProperty> 

@using (Html.BeginForm("Save", "RentalProperties", FormMethod.Post)) 
{ 
    <div class="form-horizontal"> 
     <div class="form-group"> 
      <table class="table"> 
       <tr> 
        <th> 

        </th> 
        <th> 
         @Html.DisplayNameFor(model => model.Address) 
        </th> 

       </tr> 

       @foreach (var item in Model) 
       { 
        <tr> 
         <td>@Html.CheckBoxFor(modelItem => item.IsSelected)</td> 

         <td> 
          @Html.DisplayFor(modelItem => item.Address) 
         </td> 
        </tr> 
       } 
      </table> 
     </div> 

     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Save" class="btn btn-default" /> 
      </div> 
     </div> 
    </div> 
} 

私の予想だった - 私が打ったとき「保存」ボタンをクリックすると、IEnumerable<CheckedRentalProperty>というモデルのモデルがコントローラのSave()アクションに渡されます。しかし、渡されたパラメータは常に「null」であることがわかります。私は何が欠けていますか?

+0

この質問は重複していません。オレルの答えを読んで、違いをチェックしてください – user1748546

+0

それは重複しています。あなたのコードがうまくいかない理由と 'for'ループか' EditorTemplate'を使ってそれを解決する方法を正確に説明しているので注意深く読んでください(そして、Orelの答えはちょうど重複しているものを繰り返すだけです!)そしてOrelの答え_IEnumerableのようなナンセンスが含まれていませんあなたはそれほどフレンドリーではありません。これは間違っているだけで、既存のものをラップする別のビューモデルを作成する必要は全くありません –

答えて

0

IEnumerableのみのモデルは、MVCモデルとしてあまり親切ではありません。

ここには多くの問題がありますが、簡単に言えば、MVC Webフォームバインディングでは、フォーム名要求を次の形式で送信する必要があります。PropertyName[Index].Property あなたの例ではそうではありません。

指定されたコントローラ+ページに必要なプロパティを保持するラッピングViewModelを作成するのは良い設計方法です。

のViewModel

public class RentalPropertiesViewModel 
{ 
    public List<CheckedRentalProperty> CheckedRentalProperties { get; set; } 
} 

コントローラー:次我々はコントローラで、このビューモデルを使用したいと思うでしょう。

public ActionResult Index() 
{ 
    var checkHsList = new List<CheckedRentalProperty>(); 
    checkHsList.Add(new CheckedRentalProperty { Id = 1, Address = "Address1", IsSelected = true }); 
    checkHsList.Add(new CheckedRentalProperty { Id = 2, Address = "Address2", IsSelected = false }); 
    checkHsList.Add(new CheckedRentalProperty { Id = 3, Address = "Address3", IsSelected = true }); 

    var model = new RentalPropertiesViewModel 
    { 
     CheckedRentalProperties = checkHsList 
    }; 
    return View(model); 
} 

[HttpPost] 
public ActionResult Save(RentalPropertiesViewModel model) 
{ 
    // why checkHsList is coming as null ?? 

    return null; 
} 

ビュー:は今我々の見解では、我々は我々が作成した新しいViewModelにタイプとしてモデルを設定する必要があります。

@model TestBindings.Models.RentalPropertiesViewModel 

そして、我々のビューのフォームは次のようなものでなければなりません:私は次の形式model => model.CheckedRentalProperties[i].IsSelectedを使用してきたし、今のMVC InputExtensionsはそれを正しくバインドします

<table class="table"> 
    <tr> 
     <th> 
      Is Selected 
     </th> 
     <th> 
      Address 
     </th> 

    </tr> 
    @for (int i = 0; i < Model.CheckedRentalProperties.Count(); i++) 
    { 
     <tr> 
      @Html.HiddenFor(model => model.CheckedRentalProperties[i].Id); 
      <td>@Html.CheckBoxFor(model => model.CheckedRentalProperties[i].IsSelected)</td> 

      <td>@Html.TextBoxFor(model => model.CheckedRentalProperties[i].Address)</td> 
     </tr> 
    } 
</table> 

例えば:CheckedRentalProperties[0].IsSelected

重要な注意:MVCバインダーが正しい項目にIDを設定するために知っているので、私は、隠されたとしてIdプロパティを渡している注意してください。

+0

ありがとう、Orel。できます。 – user1748546

関連する問題