So for in my series covering ASP.NET Core MVC tag helpers, I have covered all the tag helpers that you would use to generate the contents of a form:
In this post, I will cover the Form tag helper that is used to bind a Form element to a particular MVC controller action or named route. This tag helper is an alternative to the following HTML helper method syntax:
@using (Html.BeginForm("ControllerName", "ActionName")) |
Binding to Controller Action
With the form tag helper, you can bind a form to a specific controller action by adding the asp-controller and asp-action tag helper attributes to a form element.
For example, you can bind a form to the Login action of the Account controller as follows:
<form asp-controller="Account" |
Any elements that you add inside the form will be included in the generated HTML. The example above would generate the following HTML:
<form action="/Account/Login" method="post"> |
The form method was defaulted to post. You can specify this manually in your markup if you want. Any HTML attributes you add to the form element will be included in the generated HTML. However, if you attempt to both manually set the action attribute AND the asp-controller / asp-action attributes, the form tag helper will raise an error.
Cannot override the ‘action’ attribute for
<form>
. A<form>
with a specified ‘action’ must not have attributes starting with ‘asp-route-‘ or an ‘asp-action’ or ‘asp-controller’ attribute.
The form tag helper also automatically adds an Anti forgery token which will cover in more detail below.
Adding Parameters
In some cases, you might need to specify additional parameters for the controller action that you are binding to. You can specify values for these parameters by adding attributes with the asp-route- prefix. For example, it is common for the Login action to have a returnUrl parameter. This can be specified as follows:<form asp-controller="Account"
asp-action="Login"
asp-route-returnurl="@ViewBag.ReturnUrl"
method="post" >
</form>
…which would generate a form element with the action attribute containing the specified value for the returnurl parameter:<form action="/Account/Login?returnurl=%2FHome%2FAbout" method="post">
//Your form elements here
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8AFtmUdx-b5MkQvAyGYbjFmMGSMv0Fmk7gG4RqGXlkNV6yqKqj6fgqnOh4TLT6ZnWSaqtAbKkgpEB20lvfkc2iOKZKIqt3tJ4Jij8DjmatTrZo-DKVOLwwOzj3kB8VKpFwc0rQMjaJTTC_gVv5f0vAg">
</form>
You can specify values for as many parameters as you need using attributes with the asp-route- prefix.
Binding to a Named Route
Another option is to specify the controller and action using a named route. For example, if I had a route named login defined as follows in my MVC route configuration:routes.MapRoute(
name: "login",
template: "login",
defaults: new { controller = "Account", action = "Login" });
Then I could bind my form to the login route using the asp-route tag helper attribute:
<form asp-route="login" |
…which would generate the following HTML:<form action="/login?returnurl=%2FHome%2FAbout" method="post">
//Your form elements here
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8AFtmUdx-b5MkQvAyGYbjFmMGSMv0Fmk7gG4RqGXlkNV6yqKqj6fgqnOh4TLT6ZnWSaqtAbKkgpEB20lvfkc2iOKZKIqt3tJ4Jij8DjmatTrZo-DKVOLwwOzj3kB8VKpFwc0rQMjaJTTC_gVv5f0vAg">
</form>
Anti-Forgery Token Option
As we saw earlier, the form tag helper attribute adds a hidden __RequestVerificationToken input. This hidden input contains an anti-forgery token that when used in combination with the [ValidateAntiForgeryToken]
attribute on the controller action will help to protect your application against cross-site request forgery. You really should use this on all your forms but if for some reason you need to turn this off for a particular form, you can simply set the asp-anti-forgery token to false.
<form asp-controller="Account" |
Conclusion
That wraps up the functionality provided by the form tag helper in ASP.NET Core MVC. I think it provides a much cleaner syntax than the @using(Html.BeginForm()){…}
syntax. What do you think? What will be your preferred syntax for forms in MVC?