The ASP.NET Core Form Tag Helpers Cheat Sheet

January 22, 2019 · 6 minute read · Tags: mvc

How to get data from your HTML forms to ASP.NET Core (using Tag Helpers).

The Form itself (MVC)

CSHTML

@model FormsCheatSheet.Models.Example

<form asp-controller="Example" asp-action="Save" >
    <button type="submit">Submit Form</button>
</form>

The Controller

public class ExampleController : Controller
{
    public IActionResult Index() 
    {
        return View(new Example());
    }
   
   [ValidateAntiForgeryToken]
    public IActionResult Save(Example model)
    {
        // do something with model e.g. model.Name
        return Ok();
    }
}

Resulting HTML

<form action="/Example/Save" method="post">
    <input name="__RequestVerificationToken" type="hidden" 
    value="<random-looking-value=here>">
</form>

Using default ASP.NET Core MVC routing, a request to view https://<your-app-here>/example will invoke the Index method which returns Example\Index.cshtml (including our form).

When that form is submitted, the data will be routed to Save and the model populated with any submitted values.

The __RequestVerificationToken is automatically generated by ASP.NET and included as a hidden field. When the form is submitted this will be included in the form data and ASP.NET will validate it to ensure this is a legitimate request.

This helps ensure the form isn’t some spoof form someone has created on a different web site, pointing to your application.

The Form itself (Razor Pages)

CSHTML

@model FormsCheatSheet.Models.Example

<form asp-page="About">
    <button type="submit">Submit Form</button>
</form>

The Razor Page (About.cshtml.cs)

public class AboutModel : PageModel
{
    public void OnGet()
    {
    }

    public void OnPost()
    {
        // form will submit to here
    }
}

Resulting HTML

<form action="/About" method="post">
    <input name="__RequestVerificationToken" type="hidden" 
    value="<random-looking-value=here>">
</form>

Here we explicitly inform ASP.NET that this form will post back to the About page.

ASP.NET Core will then attempt to locate and invoke an OnPost method in the About page’s Page Model (About.cshtml.cs) to handle the submitted form data.

Try these Tag Helpers for yourself

Pop your email in the box below to gain access to the susbcribers only vault where you'll find tutorials, videos, and source code, including an interactive example app (complete with source) showing these Tag Helpers working in practice.

I respect your email privacy. Unsubscribe with one click.

    Label

    CSHTML

     <label asp-for="Name"></label>
    

    Model

    [Display(Name = "Full Name")] 
    public string Name { get; set; }
    

    Resulting HTML

    <label for="Name">Full Name</label>
    

    If you provide a [Display(Name=""]) its value will be used for the label, otherwise you’ll just get the name of the property itself e.g. Name.

    Text Input

    CSHTML

    <input asp-for="Name" />
    

    Model

    public string Name { get; set; }
    

    Resulting HTML

    <input type="text" id="Name" name="Name" value="">
    

    ASP.NET Core will infer that this should be an input of type text because the ‘Name’ property on the model is a string.

    When this form is submitted the Name property on the model will be populated using the value entered in the form.

    Password Input

    CSHTML

    <input asp-for="Password" />
    

    Model

    [DataType(DataType.Password)]
    public string Password { get; set; } 
    

    Resulting HTML

    <input type="password" id="Password" name="Password">
    

    ASP.NET Core will infer that this should be an input of type password because of the [DataType] attribute.

    Alternatively you can just specify this yourself in the CSHTML markup e.g. <input asp-for="Password" type="password"/>.

    When this form is submitted, Password will be populated using the value entered in the form.

    Textarea

    CSHTML

    <textarea asp-for="Bio" />
    

    Model

    public string Bio { get; set; } 
    

    Resulting HTML

    <textarea id="Bio" name="Bio"></textarea>
    

    When submitted, Bio will be populated using the value entered.

    Dropdown list (Select)

    CSHTML

    <select asp-for="Country" asp-items="Model.Countries"></select>
    

    Model

    public List<SelectListItem> Countries { get; set; }
        = new List<SelectListItem>
        {
            new SelectListItem("UK", "UK"),
            new SelectListItem("USA", "USA"),
            new SelectListItem("France", "FR")
        }; // used to populate the list of options
    
    public string Country { get; set; }
    

    Resulting HTML

    <select id="Country" name="Country">
        <option value="UK">UK</option>
        <option value="USA">USA</option>
        <option value="FR">France</option>
    </select>
    

    The select tag helper needs to know where to fetch its list of options from.

    Unlike the asp-for attribute (which assumes everything you try to use is on the Model), you have to explicitly tell asp-items where the list is coming from. In this case, Model.Countries.

    When the form is submitted Country will be set to the selected value in the dropdown list.

    Hidden Field

    CSHTML

    <input asp-for="ApplicationType" />
    

    Model

    [HiddenInput]
    public string ApplicationType { get; set; } = "Online";
    

    Resulting HTML

    <input type="hidden" id="ApplicationType" name="ApplicationType" value="Online">
    

    Occasionally you may need to include a value in the submitted form data but not show it on the page.

    You can use hidden fields for this, setting them to a value which will then be posted back when the form is submitted.

    The [HiddenInput] attribute means that ASP.NET will infer this should be a hidden field.

    Alternatively you can set this yourself in the CSHTML.

    <input type="hidden" asp-for="ApplicationType">

    In this example the ApplicationType of ‘Online’ will be sent “up” to the client and rendered as a hidden input. When the form is subsequently submitted this value will be included in the submitted form data and the ApplicationType property on the model will be set accordingly.

    Checkbox

    CSHTML

    <input asp-for="AcceptsTerms" />
    

    Model

    public bool AcceptsTerms { get; set; }
    

    Resulting HTML

    <input type="checkbox" data-val="true" id="AcceptsTerms" 
    data-val-required="The AcceptsTerms field is required." 
    name="AcceptsTerms" value="true">
    

    ASP.NET Core will infer that the input should be of type “checkbox” if you point it at a Boolean property on your model.

    The value attribute here is a little confusing as it seems to always be true. However, there is another attribute which isn’t visible in the rendered markup called checked and this is the important one which will change depending on whether the checkbox is ticked or not.

    When the form is submitted the posted form data will include a true or false and the AcceptTerms property on the model will be populated accordingly.

    Because the boolean property on the model cannot be null (has to be either true or false) ASP.NET also generates validation attributes here indicating that this input is required.

    This is largely irrelevant though as, even f your users don’t touch the checkbox, a false value will be posted when the form is submitted and the Model property will be set accordingly.

    Radio Button

    CSHTML

    <label><input asp-for="Gender" value="M" type="radio" />Male</label>
    <label><input asp-for="Gender" value="F" type="radio"/>Female</label>
    

    Model

    public string Gender { get; set; }
    

    Resulting HTML

    <label><input value="M" type="radio" id="Gender" name="Gender">Male</label>
    <label><input value="F" type="radio" id="Gender" name="Gender">Female</label>
    

    Radio Buttons are different to checkboxes in that they generally come in groups of two or more and you can only select on of the possible options.

    In this scenario the user can select Male or Female and the Gender property on the model will be set accordingly.

    Try these Tag Helpers for yourself

    Pop your email in the box below to gain access to the susbcribers only vault where you'll find tutorials, videos, and source code, including an interactive example app (complete with source) showing these Tag Helpers working in practice.

    I respect your email privacy. Unsubscribe with one click.

      Next up

      But, which flavor of ASP.NET?
      Blazor, Razor, MVC… what does it all mean?!
      What to focus on when learning ASP.NET Core?
      I’m at a bit of a loss for what I should be focusing on when learning ASP.NET…
      MVC vs Razor Pages - A quick comparison
      If you’re learning ASP.NET in this brave new .NET Core world and you want to build server-side web applications then it’s a straight fight between MVC and Razor Pages.