Join Jess Chadwick for an in-depth discussion in this video Building a form with tag helpers, part of ASP.NET Core: Razor Pages.
- [Instructor] At this point in the course, I've shown you how to build a mostly read-only site, retrieving data from a database and dynamically rendering it into HTML to display to users. The majority of applications, however, have some need to accept data sent by the user. So in this chapter, I'm going to dive into a Razor feature called Tag Helpers that will help you generate the proper markup for an HTML form and then accepting and validating the data that the user posts back to the server with that form.
If you're at all familiar with other web development frameworks, such as ASP.NET Web Forms, JSP, or PHP, then you've seen how each of them allows you to generate a bunch of HTML with a single tag, usually a tag that's native to that framework. For example, in Web Forms, you might write something like this to get a list of recipes in an HTML table. And at runtime, this one line may generate several hundred HTML elements for each recipe that you give it, which is pretty productive, not to mention powerful.
Frameworks like ASP.NET MVC, on the other hand, generate very little markup for you and instead put the power and responsibility of handcrafting just about all of that markup yourself. You can think of Tag Helpers as the middle ground. They take the HTML you have crafted and add to or modify to generate markup in a selective and conservative, yet useful, way. This ends up being the best of both worlds because you still have almost full control of the markup that's generated, but you don't have to write all of it manually; and you can limit the amount of complex logic in your code because that logic lives inside of the Tag Helper instead.
To begin using Tag Helpers, you must import them into each page that you plan on using them. To do that, you use the Add Tag Helper directive; but since I've already added this directive to the View Imports File earlier in the course, all of the Tag Helpers that ASP.NET Core and Razor Pages provides are already available to me in every single page. So to demonstrate Tag Helpers, I'll start by creating the basic form tag using standard markup with no Tag Helpers.
(typing) Then, within that form, I'll add a button. However, I'm going to wrap the button in a few div tags just for styling purposes; so I'll write those first. (typing) Here I have a very simple form with just a submit button styled with a little bit of Bootstrap CSS.
Now I can use Tag Helpers to easily build the input fields for this form. As their name implies, Tag Helpers are only available as attributes on an HTML tag; and to demonstrate how to use them, I'll create a field for the recipe name. I'll start with an empty input tag, which I'll create by copying the set of stylized markup I just created to hold the button, then replace the button tag with an input tag.
(typing) The Tag Helpers that Microsoft provides all start with the ASP- prefix; so to see what's available on any given tag, you can begin typing an attribute that starts with ASP- and see what IntelliSense options you have. The one you'll use the most is ASP-4, and it accepts a reference to a property on the page model.
So in order to generate the proper input tag for the recipe's name property, I'll say recipe.name here. When I apply the ASP-4 Tag Helper to this input tag, it will inspect the recipe.name property on my model and generate the appropriate type, name, and value attributes on the resulting markup in the input tag. To see it in action, I'll run the page.
Then I'll inspect the element and find that Razor has removed the ASP-4 attribute and replaced it with the attributes I just mentioned. Notice, however, that the Tag Helper only augmented my tag and did not modify the rest of the HTML that I wrote manually since my CSS classes are still intact. Also notice the input name that that Tag Helper generated and how it is prefixed with the text recipe underscore. That's because that's the full path to the property that I provided, starting with the page model class itself as the root.
In other words, if I had pointed the ASP-4 Tag Helper to a property named name that lived right on the page model itself, this prefix would not have been generated. Likewise, I can put the ASP-4 Tag Helper attribute on the field's label and leave the text of the label empty. (typing) I'll simply create a label tag and apply the ASP-4 Tag Helper specifying that I'd like this tag to describe the recipe's name property.
Note that I've left the content of this label empty since when the page is executed, the ASP-4 Tag Helper will inspect the recipe's name property to determine what its label should be and then populate that label's text with whatever that value is. Now that I've shown one field, I'll go ahead and do the same to create fields for each of the properties on the recipe that I want to edit. First, I'll create the description field by copying the name field and replacing its references to recipe.name with recipe.description.
I'll also change the input field to a text area tag and specify that the text area should have three rows to allow users more space to type. (typing) Then I'll do the same thing for both the ingredients and direction fields, copying the description field and replacing references to description with ingredients and then directions. (typing) I'll also give users five rows of space to edit in since these properties will have a lot of text.
Notice how for these other fields I've decided to use a text area tag, yet the Tag Helper will work just the same on these tags as well. As the list of IntelliSense options showed, there are plenty more Tag Helpers available than the couple I've shown here. I'll show you a few more when I apply validation to this form, but you'll probably want to check out Microsoft's online documentation to see the full list of helpers and how to use each one.
- Creating a new application
- Setting up pages
- Rendering dynamic content
- Reusing markup with layouts
- Increasing the maintainability of pages
- Processing data
- Validating input
- Securing an application