14
votes

I would like to ask, how can I bind an array in Asp.NET Core MVC ?

<input type="text" asp-for="Requests[@index].Name" />

It was working very well in older versions of ASP MVC. This example shows "Internal server error".

"An error occurred during the compilation of a resource required to process this request. Please review the following specific error details and modify your source code appropriately."

ViewModel class example:

public class ViewModel
{
    public List<Model> Requests {get;set;}
}

Model class example:

public class Model
{
    public string Name {get;set;}
}

How it should work ? After you submit a form with these inputs, MVC should automaticly create and map the list in ModelView. That's how It works in ASP.NET MVC 4.

2
Can you explain further what you're trying to achieve? – Techy
I added more description. – wh1sp3r

2 Answers

29
votes

You need to use a valid expression with asp-for that can be compiled, basically if index is a variable you are using in a for loop then you would write <input asp-for="@Model.Requests[index].Name" />

Full example (I've used i as the loop variable instead of index):

@model MyProject.TodoItemList

<ul>
@for (int i = 0; i < Model.Requests.Count; i++)
{
    <li>                
        <label asp-for="@Model.Requests[i].Name"></label>
        <input asp-for="@Model.Requests[i].Name"/>
        @* Or the old html helpers if you prefer
           @Html.DisplayFor(model => model.Requests[i].Name)
        *@                
    </li>
}
</ul>

For more info, check Expression names and Collections in the docs

3
votes

If you want to bind the list using a separate partial view:

First, create your action that returns the list.

public async Task<ActionResult> UpdateTable([FromForm]Filter filter)
{
    if (ModelState.IsValid)
    {           
        List<Model> model = new List<Model>();
        ViewData.TemplateInfo.HtmlFieldPrefix = string.Format("Requests");
        return PartialView("_PartialViewOfModel", model);
    }
    return BadRequest(ModelState);
}

And this code will go in your partial view.

@model List<Model>
@for (int i = 0; i < Model.Count; i++)
{
    <input type="text" class="form-control form-control-sm" asp-for="@Model[i].Name" />
}