2012-02-03 6 views
21

モデルのサブコレクションを編集するのに長時間立ち往生しましたが、モデルのコレクションがnullになりました。Asp:net MVC 3:@ Html.Editorテンプレート内の私のモデルのサブコレクション?

私は最終的に解決策を見つけたが、私はそれ少し汚れ見つける:

まず私のテストの件のデータ:

Modelオブジェクト

public class ContainerObject 
    { 
     public String Title { get; set; } 
     public List<ContainedObject> ObjectList { get; set; } 
    } 

サブコレクションオブジェクト

public class ContainedObject 
{ 
    public int Id { get; set; } 
    public String Text { get; set; } 
    public Boolean IsSelected { get; set; } 
} 

編集オブジェクト

[HttpPost] 
    public ActionResult TestFormResult(ContainerObject filledObject) 
    { 
     return View(); 
    } 

@model WebTestApplication.Models.ContainerObject 

@{ 
    ViewBag.Title = "TestForm"; 
} 
@using (Html.BeginForm("TestFormResult","Home", FormMethod.Post)){ 
    @Html.EditorFor(x => x.Title) 
    Html.RenderPartial("ContainedObject", Model.ObjectList); 
    <input type="submit" value="Submit"/> 
} 

部分Vを受け取るオブジェクト

public ActionResult TestForm() 
    { 
     return View(new ContainerObject() 
     { 
      Title = "This is a sample title", 
      ObjectList = new List<ContainedObject>() 
       { 
        new ContainedObject(){Id=1, IsSelected = true, Text="ObjectOne"}, 
        new ContainedObject(){Id=2, IsSelected = false, Text="ObjectTwo"}, 
        new ContainedObject(){Id=3, IsSelected = true, Text="ObjectThree"}, 
        new ContainedObject(){Id=4, IsSelected = false, Text="ObjectFour"}, 
       } 
     }); 
    } 

コントローラを生成するコントローラメソッドをIEW(ContainedObject.cshtml)

@model IEnumerable<WebTestApplication.Models.ContainedObject> 
@{ 
    ViewBag.Title = "ContainedObject"; 
    int i = 0; 
} 
@foreach (WebTestApplication.Models.ContainedObject currentObject in Model) 
{ 
    <br /> 
    @Html.Label(currentObject.Text); 
    @Html.CheckBox("ObjectList[" + i + "].IsSelected", currentObject.IsSelected);                          
    @Html.Hidden("ObjectList[" + i + "].Id", currentObject.Id);                         
    @Html.Hidden("ObjectList[" + i + "].Text", currentObject.Text); 
    i++; 
} 

これは、実際に働いているが、私は一つの問題ました:私は名前を自分で生成し、コンテナオブジェクトのプロパティを指定するためにきた

Html.RenderPartialの代わりにHtml.EditorForを使用しようとしましたが、問題はそれが私に "ObjectList。[0] .Id"という名前を生成するということです。プロパティ名とアクセサーの間)。

また、部分ビューで@ Html.EditorForのみを使用しようとしましたが、オブジェクトの名前でvarsを作成しました。

私は任意のテンプレートを使用しない場合、それは動作します:

@model WebTestApplication.Models.ContainerObject 

@{ 
    ViewBag.Title = "TestForm"; 
} 
@using (Html.BeginForm("TestFormResult", "Home", FormMethod.Post)) 
{ 
    @Html.EditorFor(x => x.Title) 
    for (int i = 0; i < Model.ObjectList.Count; i++) 
    { 
     <br /> 
     @Html.Label(Model.ObjectList[i].Text); 
     @Html.CheckBoxFor(m => Model.ObjectList[i].IsSelected); 
     @Html.HiddenFor(m => Model.ObjectList[i].Id); 
     @Html.HiddenFor(m => Model.ObjectList[i].Text); 
    } 

    <br /><input type="submit" value="Submit"/> 
} 

しかし、ここでそれは単純なテンプレートですが、私の実際のケースでは、私はより多くのデータを持つことになりますし、これは再利用されます複数回。だから私の最高のオプションは何ですか?

答えて

38

EditorTemplateを導入することでコードを簡素化できます。

TestFormをする:ここではどのようにです:私たちはEditorForとれるrenderPartialを置き換える以外

  • メインビューはほとんど同じまま。CSHTML

    @model WebTestApplication.Models.ContainerObject 
    
    @{ 
        ViewBag.Title = "TestForm"; 
        Layout = "~/Views/Shared/_Layout.cshtml"; 
    } 
    
    @using (Html.BeginForm("TestFormResult", "Home", FormMethod.Post)) { 
        @Html.EditorFor(m => m.Title) 
        @Html.EditorFor(m => m.ObjectList); 
    
        <input type="submit" value="Submit" /> 
    } 
    
    • その後EditorTemplates下のビュー/ホームという名前のフォルダを作成し(と仮定すると、あなたのコントローラをホームである):

    enter image description here

    • し、以下を追加しますContainedObjのテンプレート電気ショック療法

    ContainedObject.cshtml

    @model WebTestApplication.Models.ContainedObject 
    
    <p> 
        @Html.DisplayFor(m => m.Text) 
        @Html.CheckBoxFor(m => m.IsSelected) 
        @Html.HiddenFor(m => m.Id) 
        @Html.HiddenFor(m => m.Text) 
    </p> 
    

    は、エディタは自動的にそれらのそれぞれのビューをレンダリングするオブジェクトのリストを繰り返し処理します。それが役に立てば幸い。

+1

アメージング!それがリストであれば、editorForまたはDisplayForが自動的に反復することはわかりませんでした!それを使用する必要があるテンプレートを指定するときに動作させる方法はありますか? – J4N

+0

実際には、チェックボックス(複数選択)またはラジオボタン(1つの項目選択)で、同じコントローラ(選択値とデフォルト値など)で表示できる情報が数回あるので、 – J4N

+0

指定したい別のテンプレート?その場合、テンプレート名を受け入れるEditorForのオーバーロードがあります。 –

5

何か他のものを探している間にこのスレッドが見つかりました。 Denisには正しい答えがありますが、他の誰かがこの問題を遭遇した場合のための構文を追加すると考えました:

"SomeTemplate.cshtml"という名前のエディタテンプレートがある場合、次のようにItemのリストに使用できますあなたのビュー:エディタテンプレートのその後

@for (var i = 0; i < Model.ObjectList.Count(); i++) 
{ 
    @Html.EditorFor(m => m.ObjectList[i], "SomeTemplate") 
} 

@model WebTestApplication.Models.ContainedObject 

<br /> 
@Html.Label(Model.Text); 
@Html.CheckBoxFor(m => m.IsSelected); 
@Html.HiddenFor(m => m.Id); 
@Html.HiddenFor(m => m.Text); 
関連する問題