<input type="hidden"> in ASP.Net Core Razor Pages

Shervan360 1,661 Reputation points
2023-08-02T17:21:40.37+00:00

Hello,

I used an explicit index for editing a form. Why do we need an input hidden element when explicitly writing and pointing to a specific row for editing?

Thanks in advance

Screenshot 2023-08-01 222921

namespace CityBreaks.Models
{
    public class Country
    {
        public int Id { get; set; }
        public string CountryName { get; set; }
        public string CountryCode { get; set; }
    }

}

 These two lines can point to a specific tag. So why do we need a hidden element?

   <input name="Inputs[@country.Id].CountryCode" 
 <input name="Inputs[@country.Id].CountryName" 
@page
@model CityBreaks.Pages.CountryManager.EditModel
@{
}
<h4>Edit Countries</h4>

<div class="row">
    <div class="col-md-8">
        <form method="post">
            <table class="table table-borderless">
                <tr>
                    <th>Name</th>
                    <th>ISO-3166-1 Code</th>
                </tr>
                @foreach (var country in Model.Inputs)
                {
                         <input type="hidden" name="Inputs.Index" value="@country.Id" /> //Why do we need this tag when we explicitly write and point to specific row in our list ?
                    <tr>
                        <td class="w-75">
                       <input name="Inputs[@country.Id].CountryName" 
                                          value="@country.CountryName" 
                            class="form-control" />
                    </td>
                        <td class="w-25">
                        <input name="Inputs[@country.Id].CountryCode" 
                            value="@country.CountryCode" 
                            class="form-control" />
                    </td>
                    </tr>
                }
            </table>
            <div class="form-group">
                <input type="submit" value="Update" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>
@if (Model.Countries.Any())
{
    <p>You submitted the following</p>
    <ul>
    @foreach (var country in Model.Countries)
    {
        <li>
            <img src="/images/flags/@(country.CountryCode).png" />
            @country.CountryName
        </li>
    }
    </ul>
}
using CityBreaks.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace CityBreaks.Pages.CountryManager
{
    public class EditModel : PageModel
    {
        [BindProperty]
        public List<InputModel> Inputs { get; set; }
        public List<Country> Countries { get; set; } = new List<Country>();
        public void OnGet()
        {
               
            Inputs = new List<InputModel> {
                new InputModel{ Id = 840, CountryCode = "us", CountryName ="United States" },
                new InputModel{ Id = 826, CountryCode = "en", CountryName = "Great Britain" },
                new InputModel{ Id = 250, CountryCode = "fr", CountryName = "France" }
            };
        }

        public void OnPost()
        {
            Countries = Inputs
                .Where(x => !string.IsNullOrWhiteSpace(x.CountryCode))
                .Select(x => new Country
                {
                    Id = x.Id,
                    CountryCode = x.CountryCode,
                    CountryName = x.CountryName
                }).ToList();
        }

        public class InputModel
        {
            public int Id { get; set; }
            public string CountryName { get; set; }
            public string CountryCode { get; set; }

        }
    }
}
ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,815 questions
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. AgaveJoe 1,510 Reputation points
    2023-08-02T20:36:04.9866667+00:00

    Why do we need an input hidden element when explicitly writing and pointing to a specific row for editing?

    This pattern, "explicit index", is used by the model binder to populate the element of a collection. This pattern is found when a for loop is NOT used to index the input names sequentially; [0], [1], [2]. For example, using a primary key as the explicit index. This pattern allows the model binder to figure out which properties go together in a collection of complex types.

    0 comments No comments

  2. Bruce (SqlWork.com) 74,936 Reputation points
    2023-08-02T20:58:35.8333333+00:00

    its your code. we don't know why the hidden field. its name does not match the model. as there are multiple it should bind to a list or array on Model.Inputs.Index[], Model.Inputs is a List, not an object. you probably wanted Model.Inputs[index].Id

    also the binding for the input fields is wrong. you are using a code as the index, but the list is only 3 elements (0-2). try:

    @for(var i=0; i < Model.Inputs.Count; ++i)
    {
       var country = Model.Inputs[i];
       <tr>
         <td class="w-75">
            <input type="hidden" name="Inputs.Index[@i].Id" value="@country.Id" />
            <input name="Inputs[@i].CountryName" value="@country.CountryName" class="form-control" />
         </td>
         <td class="w-25">
             <input name="Inputs[@i].CountryCode" value="@country.CountryCode" class="form-control" />
         </td>
       </tr>
    }
    
    0 comments No comments

  3. Ruikai Feng - MSFT 2,761 Reputation points Microsoft External Staff
    2023-08-03T06:35:38.99+00:00

    Hi,@Shervan360

    It's for modelbinding ,Model binding would attempt to use index as the index for the collection;

    In this scaniro,the numbers inside [ ] doesn't have to start with 0 and keep consecutive,If you remove it,you would fail the model binding:

    User's image

    You could check the document related with supported formats for collection in model binding

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.