Sebastian
Sebastian

Reputation: 4811

Post Multiple List of objects in MVC

Can i submit a form that contains 2 sets of Objects , My model looks like this

        public class Item 
    {

    public int Id{get;set;}
            public bool Selected{get;set;}
    public string Name {get;set;}
    public string Price {get;set;}

    }

    public class Translations
    {

    public int Id{get;set;}
            public bool Selected{get;set;}
    public int ItemId{get;set;}
    public string Name {get;set;}
    public string TransName {get;set;}

    }

    public class ModelToSubmit
    {
    public List<Item> Items{get;set;}
    public List<Translations> TransItems{get;set;}
    }

How can i submit a ModelToSubmit to controller ? Any Idea? {Want to fetch all selected entries from Items and TransItems of ModelToSubmit

Upvotes: 3

Views: 7218

Answers (4)

RollerCosta
RollerCosta

Reputation: 5176

I hope you are aware of MVC ModelBinding and Stringly Typed Views, if not then get familiar with those first.

MVC Modelbinding uses the name attribute of html tag to match it with the corresponding Entity property.

Modifying your Entity a bit for better understanding

ENTITY

public class ModelToSubmit
   {
    public string TestProp{get; set;}
    public List<Item> Items{get;set;}
    public List<Translations> TransItems{get;set;}
   }

VIEW

@model MVC3Stack.Models.ModelToSubmit

@using (Html.BeginForm("PostToActionName","PostToControllerName"))
{
    @Html.TextBoxFor(model => model.TestProp)
    @Html.TextBox("Items[0].ItemPropName")
    @Html.TextBox("TransItems[0].TranslationsPropName")
    <input type="submit" value="Post" />
}

ACTION

[HttpPost]
public ActionResult PostToActionName(ModelToSubmit collection)
{
   return View();
}

Upvotes: 1

Erik Funkenbusch
Erik Funkenbusch

Reputation: 93424

The easiest way to do this is with EditorTemplates. They take care of all the hard work for you.

https://stackoverflow.com/a/8513087/61164

@model MVC3Stack.Models.ModelToSubmit

@using (Html.BeginForm("Index"))
{
    <table>
    Html.EditorFor(Model.Items);
    </table>
    <table>
    Html.EditorFor(Model.TransItems);
    </table>
    <input type="submit"/>
}

Create a folder in your Controllers View folder (or shared views) called EditorTemplates, and in that folder you create a razor file named after the type of your items.

Item.cshtml

@model Item

<tr>
    <td>@DisplayFor(x => x.Id)</td>
    <td>@EditorFor(x => x.Name)</td>
    <td>@EditorFor(x => x.Price)</td>
    <td>@CheckBoxFor(x => x.Selected)</td>
</tr>

Translations.cshtml

@model Translations

<tr>
    <td>@Html.DisplayFor(x => x.Id)</td>
    <td>@Html.EditorFor(x => x.ItemId)</td>
    <td>@Html.EditorFor(x => x.Name)</td>
    <td>@Html.EditorFor(x => x.TransName)</td>
    <td>@CheckBoxFor(x => x.Selected)</td>
</tr>

Submit Action

[HttpPost]
public ActionResult Index(ModelToSubmit submitModel)
{
   return View(submitModel);
}

Upvotes: 3

Nilesh
Nilesh

Reputation: 2691

Here is your main view

@model MVC3Stack.Models.ModelToSubmit
@{
    ViewBag.Title = "Create";
}
@using (Html.BeginForm("Index1","Home", FormMethod.Post))
{
    Html.RenderPartial("ItemsPartial", Model.Items);
    Html.RenderPartial("TranslationPartial", Model.TransItems);
    <input type="submit" value="Post" />
}

Items Partial View

@{
    Layout = null;
}
<table>
    @for (int i = 0; i < 5; i++)
    {
        <tr>
            <td>
                <span>Name:</span>@Html.TextBox("Items[" + i + "].Name")
            </td>
            <td>
                <span>Price</span>@Html.TextBox("Items[" + i + "].Price")
            </td>
            <td>
                <span>Selected</span>@Html.CheckBox("Items[" + i + "].Selected")
            </td>
        </tr>
    }
</table>

Translation Partial view

@{
    Layout = null;
}
<table>
    @for (int i = 0; i < 5; i++)
    {
        <tr>
            <td>
                <span>Name</span> @Html.TextBox("TransItems[" + i + "].Name")
            </td>
            <td>
                <span>Trans Name</span> @Html.TextBox("TransItems[" + i + "].TransName")
            </td>
            <td>
                <span>Selected</span>@Html.CheckBox("TransItems[" + i + "].Selected")
            </td>
        </tr>
    }
</table>

Post action

[HttpPost]
public ActionResult Index1(ModelToSubmit submitModel)
{
   return Json("Index Success", JsonRequestBehavior.AllowGet);
}

Sample output

Sample output

And the data received in the action method enter image description here

Upvotes: -1

Samer Aburabie
Samer Aburabie

Reputation: 256

MVC uses the name attribute of html elements to bind view html controls to the model submitted to the controller, in case of lists the name attribute will be in the following format:

<input type='text' name='Items[0].Id'/>
<input type='text' name='Items[0].Name'/>
<input type='text' name='Items[0].Price'/>
.
.
.
<input type='text' name='Items[n].Id'/>
<input type='text' name='Items[n].Name'/>
<input type='text' name='Items[n].Price'/>

and for transItems

<input type='text' name='TransItems[0].Id'/>
<input type='text' name='TransItems[0].Name'/>
<input type='text' name='TransItems[0].Price'/>
.
.
.
<input type='text' name='TransItems[m].Id'/>
<input type='text' name='TransItems[m].Name'/>
<input type='text' name='TransItems[m].Price'/>

so you need to be sure that your html controls related to Items and TransItems have that format for the name attribute.

Hope that helps.

Upvotes: 2

Related Questions