On a form input, the HTML name attribute determines the key sent with its value. ASP.NET Core model binding uses that key to find values for handler parameters, model properties, and arrays. A field can display the right value yet fail to bind if its submitted name does not match what the binder expects. section 28.3.1 section 28.5.1
Match a Razor Page handler parameter
In Pages/FormHandler.cshtml, an input with asp-for="Product.Name" would normally receive the name Product.Name. If the handler parameter is named name, set the input to <input asp-for="Product.Name" name="name" />. The explicit name overrides the input tag helper’s generated name, so the posted value can match the parameter. The same approach applies to a price parameter with name="price". Submit /pages/form to inspect the bound values. section 28.3.1
For a nested property, use property names separated by periods: name="Category.Name" targets the Name property of Category. The input tag helper generates this form from asp-for="Category.Name", avoiding a typo that could leave the field unbound. If a form instead posts name="cat.name" for a Category action parameter, configure that parameter with [Bind(Prefix = "cat")] so the expected prefix matches. section 28.4.2
For an array, give multiple inputs the same name, such as Data, to collect their submitted values. To control positions rather than rely on submission order, use indexed names such as Data[1] and Data[0]. A Razor Page can expose the receiving array property with BindProperty; submitting /pages/bindings displays the resulting values. section 28.5.1
Do not confuse an input’s name with <partial name="_RowPartial" />. On a partial element, name selects a partial view; it is not a form field key. section 22.5.3
Listing 28.6 Using model binding in the FormHandler.cshtml file in the Pages folder
@page "/pages/form/{id:long?}"
@model FormHandlerModel
@using Microsoft.AspNetCore.Mvc.RazorPages
@using Microsoft.EntityFrameworkCore
<div class="m-2">
<h5 class="bg-primary text-white text-center p-2">HTML Form</h5>
<form asp-page="FormHandler" method="post" id="htmlform">
<div class="form-group">
<label>Name</label>
<input class="form-control" asp-for="Product.Name"
name="name" />
</div>
<div class="form-group">
<label>Price</label>
<input class="form-control" asp-for="Product.Price"
name="price" />
</div>
<button type="submit" class="btn btn-primary mt-2">Submit</button>
</form>
</div>
@functions {
public class FormHandlerModel : PageModel {
private DataContext context;
public FormHandlerModel(DataContext dbContext) {
context = dbContext;
}
public Product Product { get; set; }
= new() { Name = string.Empty };
public async Task OnGetAsync(long id = 1) {
Product = await context.Products
.Include(p => p.Category)
.Include(p => p.Supplier)
.FirstAsync(p => p.ProductId == id);
}
public IActionResult OnPost(string name, decimal price) {
TempData["name param"] = name;
TempData["price param"] = price.ToString();
return RedirectToPage("FormResults");
}
}
}
Compare each asp-for expression with the explicit name that lets the Razor Page bind to a handler parameter. section 28.3.1
Listing 28.17 Setting a prefix in the FormController.cs file in the Controllers folder
...
[HttpPost]
public IActionResult SubmitForm([Bind(Prefix ="cat")]Category category) {
TempData["category"] = JsonSerializer.Serialize(category);
return RedirectToAction(nameof(Results));
}
...
See how Bind(Prefix = "cat") makes a controller parameter accept fields using the custom cat prefix. section 28.4.2
Listing 28.23 Specifying array position in the Bindings.cshtml file in the Pages folder
@page "/pages/bindings"
@model BindingsModel
@using Microsoft.AspNetCore.Mvc
@using Microsoft.AspNetCore.Mvc.RazorPages
<div class="container-fluid">
<div class="row">
<div class="col">
<form asp-page="Bindings" method="post">
<div class="form-group">
<label>Value #1</label>
<input class="form-control" name="Data[1]"
value="Item 1" />
</div>
<div class="form-group">
<label>Value #2</label>
<input class="form-control" name="Data[0]"
value="Item 2" />
</div>
<div class="form-group">
<label>Value #3</label>
<input class="form-control" name="Data[2]"
value="Item 3" />
</div>
<button type="submit" class="btn btn-primary">
Submit
</button>
<a class="btn btn-secondary" asp-page="Bindings">Reset</a>
</form>
</div>
<div class="col">
<ul class="list-group">
@foreach (string s in Model.Data.Where(s => s != null)) {
<li class="list-group-item">@s</li>
}
</ul>
</div>
</div>
</div>
@functions {
public class BindingsModel : PageModel {
[BindProperty(Name = "Data")]
public string[] Data { get; set; } = Array.Empty<string>();
}
}
See indexed input names used to specify positions in a bound array. section 28.5.1

