Search code examples
data-bindingcollectionsasp.net-core-2.0razor-pages

Asp.net core razor pages [BindProperty] doesnt work on collections


Im trying to use [BindProperty] annotation in asp.net core razor pages in order to Bind an Ilist<T> collection of one of my model classes so i can edit some of them at once, but it doesnt work at all, every time in OnPostAsync function the collection is empty, and neither the changes that i made on data nor it default values wont post back to the server, but when its a singel object [BindProperty] works fine and the values post back and can be changed, i also tried wraping a collection (i.e list<T>) in an object but it didnt work either way, so is there any way for doing so or i should lets say send a edit request for every object in that collection and edit them one by one(which cant be done in razor pages easilly and need some ajax calls)??


Solution

  • For binding IList between RazorPage and PageModel, you will need to use Product[i].Name to bind property.

    Here are complete steps.

    1. Model

       public class Product
       {
          public int Id { get; set; }
          public string Name { get; set; }
       }
      
    2. PageModel

      public class IndexModel : PageModel
      {
          private readonly CoreRazor.Data.ApplicationDbContext _context;
      
          public IndexModel(CoreRazor.Data.ApplicationDbContext context)
          {
             _context = context;
          }
      
          [BindProperty] 
          public IList<Data.Product> Product { get; set; }
      
          public async Task OnGetAsync()
          {
              Product = await _context.Product.ToListAsync();
          }
      
          public async Task OnPostAsync()
          {
              var product = Product;
          }
      }
      
    3. View

      <form method="post">
          <table class="table">
              <thead>
                  <tr>
                      <th>
                          @Html.DisplayNameFor(model => model.Product[0].Name)
                      </th>
                      <th></th>
                  </tr>
              </thead>
              <tbody>
                  @for (int i = 0; i < Model.Product.Count(); i++)
                  {
                      <tr>
                          <td>
                              <input hidden asp-for="Product[i].Id" class="form-control"/>
                              <input asp-for="Product[i].Name" class="form-control" />
                          </td>
                          <td>
                              <a asp-page="./Edit" asp-route-id="@Model.Product[i].Id">Edit</a> |
                              <a asp-page="./Details" asp-route-id="@Model.Product[i].Id">Details</a> |
                              <a asp-page="./Delete" asp-route-id="@Model.Product[i].Id">Delete</a>
                          </td>
                      </tr>
                  }
              </tbody>
          </table>
          <div class="form-group">
              <input type="submit" value="Save" class="btn btn-default" />
          </div>
      
      </form>