To finish off our routing series, we're going to spend a post looking at how to use ASP.NET Core 3.0 Anchor Tag Helpers to generate HTML anchor tags for MVC controllers and actions and Razor Pages, as well as how to access route data and query string parameters on the views and pages in our apps.
Let's get started!
Tag Helper Basics
Let's begin with a quick reminder of what Tag Helpers are. If you have no idea what I'm talking about, check out a post I wrote a few years ago explaining what tag helpers do in ASP.NET Core. The post was written for ASP.NET Core 1.0, but the ideas hold in modern versions.
Let's assume that we have the following convention-based route:
Because this is the "landing" or "default" route for our application, the following URLs will match it:
/home/index/5
/home/index
/home
/
Tag Helpers, in ASP.NET Core 3.0, are classes which allow us to write HTML on our CSHTML pages and still use server-side information, such as actions, controllers, route data, etc. A basic anchor tag helper might look like this:
<a asp-area="" asp-controller="Home" asp-action="Index">Home</a>
Note the "asp-" prefixes. This prefix must be applied to any controller, route, area, page, route data, or other item that we expect ASP.NET 3.0 to handle the processing of. In this case, our link will be to the HomeController.Index()
action.
The above tag helper generates the following HTML:
<a href="/">Home</a>
Note that the tag helper will generate the "simplest" (which is usually also the shortest) URL that will match the intended route.
Tag Helper Setup
Newly-generated .NET Core projects in Visual Studio include a file called _ViewImports.cshtml, which looks like this (example taken from the sample project):
@using RoutingAspNetCoreDemo.Endpoints
@using RoutingAspNetCoreDemo.Endpoints.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
The third line is what enables us to use tag helpers on our CSHTML views and pages. We don't need any other setup. But if you find yourself unable to use tag helpers, or having difficulty, ensure that this file exists and that particular line is in it.
Basic Routing with Anchor Tag Helpers
We can link to controllers and actions in our MVC and Razor Pages apps using "asp-controller" and "asp-action" attributes:
<a asp-controller="Home" asp-action="LinkGenerator">Link Generator</a>
We can also link to Razor Pages using "asp-page" attributes:
This tag helper generates the following HTML:
Route Parameters
Tag Helpers also include a way for us to insert route parameters into our anchor tags. In this case, we use the "asp-route-" prefix. Let's say we have another convention-based route:
endpoints.MapControllerRoute("parameters",
"parameters/{level}/{type}/{id}",
defaults: new { controller = "Home", action = "Parameters" });
This route expects a URL like the following:
We can generate that specific URL by specifying the route parameters in our anchor tag helper:
<a asp-route="parameters"
asp-route-id="19"
asp-route-type="Test Name"
asp-route-level="5">Parameters</a>
Which generates this HTML:
<a href="/parameters/5/Test%20Name/19">Parameters</a>
Routing to Areas
If we are using Areas in our ASP.NET Core 3.0 applications, we can generate anchor links to controllers, actions, or pages in areas by using the "asp-area" attribute:
<a asp-area="blog" asp-controller="Post" asp-action="Article" asp-route-title="this-is-a-test-article">Article</a>
Which generates this HTML:
<a href="/blog/Post/Article?title=this-is-a-test-article">Article</a>
Routing to Named Routes
We can also use anchor tag helpers to route to a named route. Here's one example of such a route:
endpoints.MapControllerRoute("account",
"account/{id?}",
defaults: new { controller = "Account", action = "Index" });
We can use the following tag helper to generate a link to the "/account/{id}" action, where the route value ID is 5:
<a asp-route="account" asp-route-id="5">Account</a>
This generates the corresponding HTML:
<a href="/account/5">Account</a>
Route Data vs Query String
ASP.NET Core 3.0 differentiates route data from query string data, and they are accessed in different ways. Say we again have this route:
endpoints.MapControllerRoute("parameters",
"parameters/{level}/{type}/{id}",
defaults: new { controller = "Home", action = "Parameters" });
To which the following URL is matched:
/parameters/18/title/7?postTitle=this-is-a-title
ASP.NET Core 3.0 would make the following route data:
- Level = 18
- Type = "title"
- ID = 7
But the "postTitle" value is part of the query string and therefore not part of the route data.
Accessing Route Data
To access route data in MVC views, we can use ViewContext.RouteData.Values
:
In Razor Pages, we can access route data by merely using RouteData.Values
:
@page "/article/{id:int:required}/{**title:alpha}"
@model RoutingAspNetCoreDemo.RazorPages.Areas.Blog.Pages.ArticleModel
@{}
<h2>Article Page</h2>
<p>The ID is @RouteData.Values["id"] and the title is "@RouteData.Values["title"]"</p>
Accessing Query String Parameters
In ASP.NET Core 3.0 MVC, we can access query string parameters by using @Context.Request.Query
:
<h1>Article</h1>
<p>The slug for this article is @Context.Request.Query["title"].ToString()</p>
In Razor Pages, the accessor is simpler: just @Request.Query
:
<h1>Date Article</h1>
<p>The slug for the article is @Request.Query["title"]</p>
Summary
In both ASP.NET Core 3.0 MVC and Razor Pages, creating anchor tags and accessing route data and query string parameters is pretty straightforward. Remember the following:
- Use "asp-controller", "asp-action", "asp-page", "asp-area", and "asp-route" attributes to route to the correct actions, routes, or pages.
- Use "asp-route-" prefixed attributes to include specific data in the route values for the generated link.
- Access route data by using
@ViewContext.RouteData.Values[]
(orRouteData.Values[]
in Razor Pages). - Access query string parameters by using
@Context.Request.Query[]
(orRequest.Query[]
in Razor Pages).
Don't forget to check out the sample project over on GitHub! Also, stay tuned on Wednesday, because the very first post from Joe Middour, a writer in this blog's Guest Writer Program, will be published!
Happy Routing!