Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asp:net MVC 3: @Html.EditorFor a subcollection of my model in a template?

Tags:

I've been stuck a long time to edit a subcollection of my model, the collection of the model was coming null.

I finally found a solution, but I find it a little dirty:

First my tests datas:

Model object:

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

Sub collection object:

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

Controller method which generate the object

    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"},                 }         });     } 

Controller which receive the edited object

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

The 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"/> } 

The partial view(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++; } 

This is actually working, but I've one problem:

  • I've to generate names myself and specify the property of the container object

I tried to use Html.EditorFor instead of Html.RenderPartial in the view, the problem is that it generate me the name "ObjectList.[0].Id"(with a additional . between the property name and the accessor).

I also tried to use only @Html.EditorFor in the partial view, but it create vars with the name of the object.

If I don't use any template, it works:

    @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"/> } 

But here it's a simple template, but in my real case, I will have much more data, and this will be re-used multiple time. So what is my best option?

like image 961
J4N Avatar asked Feb 03 '12 08:02

J4N


People also ask

What is editor htmlhelper in MVC?

HtmlHelper - Editor. We have seen different HtmlHelper methods used to generated different html elements in the previous sections. ASP.NET MVC also includes a method that generates html input elements based on the datatype. Editor() or EditorFor() extension method generates html elements based on the data type of the model object's property.

How do I create an HTML control in MVC?

Create HTML Controls for Model Class Properties using EditorFor () ASP.NET MVC includes the method that generates HTML input elements based on the datatype. The Html.Editor () or Html.EditorFor () extension methods generate HTML elements based on the data type of the model object's property.

How to generate HTML elements from datatype in ASP NET MVC?

ASP.NET MVC includes the method that generates HTML input elements based on the datatype. The Html.Editor () or Html.EditorFor () extension methods generate HTML elements based on the data type of the model object's property. The following table list the data types and releted HTML elements:

Which method generates HTML elements based on the datatype of the model?

ASP.NET MVC includes the method that generates HTML input elements based on the datatype. The Html.Editor () or Html.EditorFor () extension methods generate HTML elements based on the data type of the model object's property.


1 Answers

You can simplify your code by introducing the EditorTemplate. Here is how:

  • The main view remains pretty much the same except we replaced RenderPartial with EditorFor:

TestForm.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" /> } 
  • Then create a folder named EditorTemplates under Views/Home (assuming your controller is Home):

enter image description here

  • and add the following template for the ContainedObject:

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> 

The editor will automatically iterate through the list of objects rendering the view for each of them. Hope it helps.

like image 125
Denis Ivin Avatar answered Sep 20 '22 11:09

Denis Ivin