0% found this document useful (0 votes)
3 views10 pages

Routing in Razor Pages - Learn Razor Pages

The document provides an overview of Razor Pages routing in ASP.NET Core, explaining how URLs are matched to Razor pages based on file paths. It covers topics such as route templates, route data, constraints, and the use of friendly URLs, along with examples of configuring routes and generating URLs. Additionally, it discusses the importance of disambiguating routes and accessing route parameter values within page models.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views10 pages

Routing in Razor Pages - Learn Razor Pages

The document provides an overview of Razor Pages routing in ASP.NET Core, explaining how URLs are matched to Razor pages based on file paths. It covers topics such as route templates, route data, constraints, and the use of friendly URLs, along with examples of configuring routes and generating URLs. Additionally, it discusses the importance of disambiguating routes and accessing route parameter values within page models.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Home (/)

[Link] Core (/asp-net-core)

Tutorials (/razor-pages/tutorial/bakery)

Razor Page Files (/razor-pages)

Razor Syntax (/razor-syntax)

Page Models (/razor-pages/pagemodel)

Tag Helpers (/razor-pages/tag-helpers/)

View Components (/razor-pages/view-components)

Routing and URLs (/razor-pages/routing)

Customising Route Conventions (/advanced/custom-route-conventions)

Startup (/startup)

Configuration (/configuration)

Middleware (/middleware)

Dependency Injection (/advanced/dependency-injection)

Working With Forms (/razor-pages/forms)

Validation (/razor-pages/validation)

Model Binding (/razor-pages/model-binding)

State Management (/razor-pages/state-management)

Caching (/razor-pages/caching)

Managing Security With [Link] Identity (/identity)

Using AJAX (/razor-pages/ajax)

Working with JSON (/web-api)

Scaffolding (/miscellaneous/scaffolding)

Publishing To IIS (/publishing/publish-to-iis)

Advanced (/advanced)

Table Of Contents (/table-of-contents)

Razor Pages Routing


Routing is the system that matches URLs to Razor pages. Like most page-centric frameworks, the primary routing system in
[Link] Razor Pages is based on matching URLs to file paths, starting from the root Razor Pages folder, which is named Pages by
default.

How URLs are matched link


When a Razor Pages application starts up, a collection of Attribute Routes (familiar to anyone who has used them in [Link] MVC
5 or MVC Core) is constructed, using the file and folder paths rooted in the Pages folder as the basis for each route's template.

The standard Razor Pages 3.x site template includes three pages in the root folder:

[Link]
[Link]
[Link]

A collection of four routes are defined with the following route templates:

""
"Error"
"Index"
"Privacy"

By default, the route templates are generated by taking the virtual path of each content page (/razor-pages#content-pages) and
then removing the root folder name from the start and the file extension from the end.

[Link] is considered the default document in any folder, so it has two routes defined - one for the file name without the
extension, and one with an empty string representing the file. Therefore, you can access [Link] by browsing to both
[Link] and [Link] .

If you create a folder named Test and add a file named [Link] to it, a further two routes will be defined with the following
templates:

"Test"
"Test/Index"

Both of these routes will be mapped to the same virtual path: /<root>/Test/[Link] .

However, if you now add a file called [Link] to the root pages folder and attempt to browse to it, an exception will be
raised:

AmbiguousActionException: Multiple actions matched.


The following actions matched route data and had all constraints satisfied:

Page: /Test/Index
Page: /Test

As the exception message says, it is an error to have a single URL mapped to multiple actions or routes. The framework has no
way of knowing which page to call. You can disambiguate between routes by adding route parameters and/or constraints to the
template.

Areas link
Areas (/advanced/areas) were introduced to Razor Pages in [Link] Core 2.1. Routes to resources in areas have the name of
the area as the first segment of the URL.
Areas
Adminstration
Pages
[Link]
[Link]
Production
Pages
[Link]
Pages
[Link]
[Link]
[Link]

The additional routes created for the content in the areas is as follows:

"Adminstration"
"Administration/Index"
"Administration/Reports"
"Production"
"Production/Index"

The Areas folder and the Pages folder do not feature as part of the route template.

Changing the default Razor Pages root folder link


You can use configuration (/configuration) to change the root folder for Razor pages. The following example changes the root
folder from the default Pages to Content:

3.x 2.x

public void ConfigureServices(IServiceCollection services)


{
[Link]()
.AddRazorPagesOptions(options => {
[Link] = "/Content";
});
}

Or you can use the WithRazorPagesRoot extension method:

public void ConfigureServices(IServiceCollection services)


{
[Link]().WithRazorPagesRoot("/Content");
}

Note that you cannot change the root folder for pages located in areas.

Route Data link


Let's say you have created a blog. You may have a page called [Link] in your root pages folder in which you display the
content of specific posts. You provide a series of links on your home page to individual posts, and each one includes a value in
the URL to identify the specific post to retrieve from the database. You could supply this value as a query string value
( [Link]/post?title=my-latest-post ), or you could add it as Route Data - a segment in the URL that plays no part in
matching files on disk e.g. /my-latest-post in [Link]/post/my-latest-post . The last segment, or parameter is an
arbitrary piece of data passed in the URL. The Route Data approach is preferred for a number of reasons, among which it is more
readable - especially if you have a number of parameter values - and it is more search engine-friendly.

Route Templates link


Route Data parameters are defined in a Route Template as part of the @page directive in the .cshtml file. To cater for the title
value in the example above, the declaration at the top of the [Link] file will look like this:

@page "{title}"

The template created for this route is "Post/{title}" . The {title} part of the template is a placeholder that represents any
value added to the URL after post/ . The template definition must appear in double quotes, and the parameter must be
enclosed in curly brackets or braces.

In this example, the value is required, so you cannot just browse to /post . You must provide a value in the URL to match the
"title" segment, otherwise you will get a status code of 404 - Not Found. However, you can make the parameter optional by
adding a ? after it:

@page "{title?}"

Or you can provide a default value for the parameter:

@page "{title=first post}"

There is no limit to the number of parameters you can add to a route, although there is a limit to the data types that you can use
as route parameters. Only simple types, such as string, datetime, boolean and numeric types are supported. It is common to see
blog post urls include the year, month and day of publication as well as the title. A route definition that accomplishes this might
appear as follows:

@page "{year}/{month}/{day}/{title}"

 The following words are reserved and cannot be used as names for route parameters:
action

area

controller

handler

page

Accessing route parameter values link


Route parameter values are stored in a RouteValueDictionary accessible via the [Link] property. You reference
values by their string-based key:

@[Link]["title"]
The potential problem with this approach is that it relies on referencing values by strings, which are prone to typographical
errors, resulting in runtime errors. The recommended alternative is to bind the values to properties on a PageModel (/razor-
pages/pagemodel). To do this, you can add a public property of a suitable data type to the page model class and a parameter to
the OnGet() method with the same name and data type as the route parameter:

public class PostModel : PageModel


{
public string Title { get; set; }
public void OnGet(string title)
{
Title = title;
}
}

You assign the parameter value to the public property, which makes it available on the Model property in the content page:

@page "{title?}"
@model PostModel
@{
}
<h2>@[Link]</h2>

The key reason for recommending this approach is that you benefit from strong typing and therefore IntelliSense support in
IDE's that support it:

Alternatively, you can use the [BindProperty] attribute on the PageModel property with SupportsGet set to true :

public class PostModel : PageModel


{
[BindProperty(SupportsGet = true)]
public string Title { get; set; }
public void OnGet()
{
// the Title property is automatically bound
}
}

Adding Constraints link


Constraints are an additional means of disambiguating between routes. So far, the only constraint placed on a route parameter
value is its presence. You can also constrain route parameters values by data type and range (/miscellaneous/constraints). The
following example shows how to constrain a parameter value to an integer data type:

@page "{id:int}"
The id value is both required, and must be an integer. The next example illustrates an optional parameter, which must be a
double if a value is provided:

@page "{latitude:double?}"

The next example shows use of the min constraint, that ensures that the value supplied is an int and that it meets a minimum
value of 10000. The minimum value is supplied in parentheses:

@page "{id:min(10000)}"

The final example shows how to specify multiple constraints using colons:

@page "{username:alpha:minlength(5):maxlength(8)}"

This template specifies that the username values is required (i.e. is not optional), must be composed of a mixture of upper case
and lowercase letters (no numbers or other symbols), has a minimum length of 5 characters and a maximum length of 8
characters.

The range of constraints (/miscellaneous/constraints) available are extensive, but you can also create your own custom route
constraints (/advanced/custom-constraints).

Override Routes link


From [Link] Core 2.1 onward, you can use the template to specify an alternative route for a page that has no relationship with
the file name. The override route template should start with / or ~/ . For example, you may have a page located deep in the
folder structure somewhere e.g. Pages/Projects/Building/SOP/Schools/[Link] that you want to surface at an much easier to
remember URL: schools/sop . You do this by specifying the URL pattern in the template:

@page "/schools/sop"

This replaces the file-path-based URL.

You can use a similar approach to add segments to a route. This is achieved by omitting the / or ~/ from the start of the
template. The following template will require the user to add /schools to the default route that is generated for the page:

@page "schools"

Friendly Routes link


The final piece in the Razor Pages routing jigsaw is based on the "Friendly URLs" feature found in [Link] Web Forms (another
page-centric development model) which enables you to bypass the tight relationship between URL and the file path and name of
the page that's being requested.

Friendly Routes mappings can also be configured by adding options to the [Link] collection in the
ConfigureServices method in Startup (/startup) via the AddPageRoute method. In this example, a physical file named Post exists
in /Pages/Archive/. You want to enable users to reach it without prepending Archive to the URL, and you want to specify some
route parameters. You do that as follows:

3.x 2.x
services
.AddRazorPages()
.AddRazorPagesOptions(options =>
{
[Link]("/Archive/Post", "Post/{year}/{month}/{day}/{title}");
});

The AddPageRoute method takes two parameters. The first is the relative path to the Razor page file without the extension and
the second is the route template that maps to it.

Unlike Absolute Routes, friendly routes are additive, that is they do not replace existing routes. They act in a similar way to
method overloads in programming. It will still be possible to reach the resource above by navigating to /archive/post .
Consequently it is possible to add a "catchall" friendly route without affecting routes generated from physical files. The following
example illustrates a route that catches any URL that doesn't map to a physical file and gets the [Link] file to process the
request:

3.x 2.x

services
.AddRazorPages()
.AddRazorPagesOptions(options =>
{
[Link]("/index", "{*url}");
}

You might do this, for example, if your [Link] file is responsible for locating and processing Markdown files based on the
URL, as is the case with this site.

There is also a method for overloading routes to pages in areas: AddAreaPageRoute . This takes the name of the area, the name of
the page, and the route template e.g.

3.x 2.x

services
.AddRazorPages()
.AddRazorPagesOptions(options =>
{
[Link]("Administration", "/index", "admin");
}

Other Routing Options link


The routing system provides some additional configuration options via properties of the RouteOptions object which can be
accessed in the ConfigureServices method. The properties are as follows:

Property Type Description

AppendTrailingSlash bool Appends a trailing slash to URLs generated by the anchor tag helper (/razor-
pages/tag-helpers/anchor-tag-helper) or UrlHelper. Default is false
Property Type Description

ConstraintMap IDictionary<string, Enables the registration of custom constraints (/advanced/custom-


Type> constraints) via the Add method

LowercaseUrls bool URLs are generated all in lower case. The default is false

LowercaseQueryStrings bool Query strings are generated all in lower case. The default is false . Will only
take effect if LowercaseUrls is also true

Examples:

[Link]<RouteOptions>(options =>
{
[Link] = true;
[Link] = true;
[Link] = true;
[Link]("Custom", typeof(CustomConstraint));
});

Generating Urls link


Razor Pages provides two main mechanisms for generating URLs to pages within the application, depending on where they are
needed.

Anchor Tag Helper link


The anchor tag helper (/razor-pages/tag-helpers/anchor-tag-helper) is designed to be used to render anchor elements within
content pages:

<a asp-page="/Supplier" asp-route-id="2">Click</a>

You can read more about the anchor tag helper here (/razor-pages/tag-helpers/anchor-tag-helper).

The LinkGenerator link


The LinkGenerator service is available in Razor Pages 3 onwards. Registered by default with the dependency injection system,
you can use the LinkGenerator within classes (such as PageModels) to generate URLs based on the route information provided.

There are two Razor Pages specific methods for generating URLs: GetPathByPage and GetUriByPage . The GetPathByPage method
generates a relative URL, and the GetUriByPage method generates an absolute URL:
public class LinkGeneratorDemoModel : PageModel
{
private LinkGenerator linkGenerator;
public LinkGeneratorDemoModel(LinkGenerator linkGenerator) => [Link] = linkGenerator;
public string PathByPage { get; set; }
public string UriByPage{ get; set; }
public void OnGet()
{
PathByPage = [Link]("/Supplier", null, new { id = 2 });
UriByPage = [Link]([Link], "/Supplier", null, new { id = 2 });
}
}

Output:

Path By Page: /supplier/2


Uri By Page: [Link]

Note: this output assumes that the option to use lower case URLS (/razor-pages/routing#other-routing-options) is set to true .

The LinkGenerator service also provides a number of methods for working with URLs related to controllers.

Last updated: 01/04/2022 10:39:14

([Link]

utm_source=mikebrind&utm_medium=affiliate&utm_campaign=book_brind_razor_7_26_21&a_aid=mikebrind&a_bid=f71bcc8c)

On this page
Razor Pages Routing
How URLs are matched

Areas

Changing the default Razor Pages root folder

Route Data

Route Templates

Accessing route parameter values

Adding Constraints

Override Routes

Friendly Routes

Other Routing Options

Generating Urls

Anchor Tag Helper

The LinkGenerator

Latest Updates
Dates And Times in a Razor Pages Form ([Link]

Routing in Razor Pages ([Link]

The Anchor Tag Helper in Razor Pages ([Link]

Using Cookies in Razor Pages ([Link]

Caching in Razor Pages ([Link]

Publishing and deploying a Razor Pages application to IIS on Windows


([Link]

© 2018 - 2022 - Mike Brind.


All rights reserved.
Contact me at [Link]

You might also like