Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Core 1.0 POST IEnumerable<T> to controller

I have an action that returns a model to the View which is IEnumerable<T>. In the view I loop through the list using foreach. T type has a property called Amount.

Now when I click SAVE button, I want to POST the model (IEnumerable) to an action. The IEnumerbale items, their properties Amount should contain the correct values.

enter image description here

When I submit it, in the action, the model is null.

For testing the IEnumerable<T> is IEnumerable<Produt>

public class Product
{

    public string Title { get; set; }
    public int Amount { get; set; }
}

view display products:

 @model IEnumerable<Product>


 <form asp-controller="Home" asp-action="Order" method="post" role="form">
       @foreach (var product in Model)
       {
            <div>
                  <span>@product.Title</span>
                  <input asp-for="@product.Amount" type="text">
            </div>
       }
  <button type="submit">SAVE</button>         

 </form>

controller post action:

    [HttpPost]    
    public async Task<IActionResult> Order(IEnumerable<Product> model)
    {

    }
like image 615
user2818430 Avatar asked Jul 14 '16 13:07

user2818430


2 Answers

The problem was @model IEnumerable<Product> in the view. I changed that to List and use instead a for loop:

@model List<Product>


<form asp-controller="Home" asp-action="Order" method="post" role="form">
   @for (int i = 0; i < Model.Count(); i++)
   {
        <div>
              <span>@Model[i].Title</span>
              <input asp-for="@Model[i].Amount" type="text">
        </div>
   }

SAVE

like image 59
user2818430 Avatar answered Oct 17 '22 11:10

user2818430


It finally boils down to the serialization format that MVC understands for form posts (ex: application/x-www-form-urlencoded). So whenever you use TagHelpers or HtmlHelpers make sure that you try to render the form in the following way:

Action parameter: IEnumerable<Product> products
Request format: [0].Title=car&[0].Amount=10.00&[1].Title=jeep&[1].Amount=20.00


Action parameter: Manufacturer manufacturer where Manufacturer type is like below:

public class Manufacturer
{
    public string Name { get; set; }
    public List<Product> Products { get; set; }
}

public class Product
{
    public string Title { get; set; }
    public int Amount { get; set; }
}

Request format: Name=FisherPrice&Products[0].Title=car&Products[0].Amount=10.00&Products[1].Title=jeep&Products[1].Amount=20.00


Action parameter: IEnumerable<string> states
Request format1: states=wa&states=mi&states=ca
Request format2: states[0]=wa&states[1]=mi&states[2]=ca


Action parameter: Dictionary<string, string> states
Request format: states[wa]=washington&states[mi]=michigan&states[ca]=california

like image 23
Kiran Avatar answered Oct 17 '22 12:10

Kiran