liveBook · Manning

Name attribute

As explained in Pro ASP.NET Core 7, Tenth Edition

An HTML attribute that supplies the name used to identify an element's submitted value and bind it to request data.

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

How Pro ASP.NET Core 7, Tenth Edition covers it

How deep it goes
Works through explicit overrides, nested prefixes, and array indexes; does not explain model binder internals.
Examples
Tests a Razor Page form at /pages/form and array inputs at /pages/bindings.
What it assumes
Assumes familiarity with HTML forms and Razor views or pages while demonstrating how submitted names affect binding.
What you can do after
Operate/configure ASP.NET Core form binding by choosing input names or a Bind prefix that matches the receiving data.
How it connects
Connects input tag helpers and asp-for to model binding, Bind prefixes, BindProperty, and arrays.

Also explained in

Compare how 2 books explain name attribute →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Pro ASP.NET Core 7, Tenth Edition. The section links point to the parts of the book it draws on.