2. Routing
In ASP.NET Core MVC, routing is the process of mapping an incoming
HTTP request to a specific action method
Before routing, URLs typically mapped to a physical file on disk
For example, the URL ‘../products.aspx’ would map to a file named
‘products.aspx’ in the application folder
This may be simpler than routing, but has disadvantages:
If you change the file name, all links to the page within the application need to
be changed
URLs exposed to users need to be changed
3. Benefits of routing
Routing allows us to define URLs that are not tied to particular
files or structure of our application
It decouples action methods from the URLs that are used to
execute them
If you need to change URLs, you only need to modify the
routing system; action methods remain unchanged
4. Routing terms
Route template
Defines a URL pattern that is used to match against request URLs
A template is a string that contains placeholders for parts that may vary
For example, a route template {controller}/{action}, would map the
URL ‘www.localhost:12345.com/product/view’ to
ProductController.View() action method
5. Route template
A single route template can map a number of different URLs
For example, the same route template would map the URL
‘home/index’ to HomeController.Index() action method
An application can have more than one routing template
6. Routing terms
URL segment
A small, contiguous section of a URL
They are separated by a character, often by the ‘/’ character
Routing involves matching the segments of a URL to a route template
7. Routing in MVC
Two ways to define routes:
Routing using conventions
Routing using attributes
In this chapter we will cover routing using conventions
8. Routing using conventions
Defined in the Startup.cs file:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
EndPointMiddleware is where you configure all the endpoints
An endpoint is some handler that returns a response
Route name: a name that can be used by other parts of the program
Pattern: the route template
10. Defining multiple routes
The order of routes is important
It defines the order against which the routing infrastructure will attempt to
match an incoming request
You should list the most specific routes first, in order of decreasing
specificity, until you get to the most broad/general route
11. Route template syntax
It consists of segments, separated by “/’
A segment can be
A literal
A route parameter
A literal must be matched exactly by the request URL
A parameter is a section of a URL that may vary, but still be a match for the template
Route parameters are defined by giving them a name, and placing them in braces, such
as {controller} or {action}
12. How do routing templates work?
For each defined route template, the router attempts to split the request’s URL into segments
corresponding to the template
For example, suppose we have this template:
{controller}/{action}
and the URL is: /products/view
The EndPointMiddleware will split the URL into segments corresponding to the template
In this case, the URL matches the pattern of the template
It has 2 segments
When there is a match, values associated with the parameters are stored in a collection associated
with the request
In our example:
value associated with {controller} parameter is ‘products’
value associated with {action} parameter is ‘view’
Then using these values, EndPointMiddleware attempts to find a controller named
‘productsController’ that contains an action named ‘view’
13. How do routing templates work? (cont’d)
Supposed we have a different request URL, for example:
/products/books/view
This URL with three segments does not match the route template
{controller}/{action}
The EndPointMiddleware will compare it against other route templates, if
there are more
If no match is found, a 404 response will be generated
14. How do routing templates work? (cont’d)
Literal segments
Consider the route template below, that contains a literal segment
sales/{controller}/{action}
The URL below will be a match; it has three segments and the first is ‘sales’:
sales/products/view
However, this other URL, will not be a match, because the first segment is not exactly ‘sales’ as
specified in the template
rentals/products/view
15. Default values
Consider the template below:
{controller}/{action=Index}
The {action} parameter has a default value specified for it, Index
This means that if the URL doesn’t contain a segment corresponding to the action
parameter, then the router will use the value ‘Index’ instead
For example, both these two URLs will match this template
/products/view (executes View action in ProductsController)
/products (executes Index action in ProductsController)
16. Optional parameters
Consider the template below:
{controller}/{action=index} /{id?}
Third segment, id, is an optional parameter
If present, the router will capture the value, otherwise it will not create a route value for
id
Both URLs below will be a match for this template
products/view/100
products/view
17. Constraints
Routing only matches URL segments to route parameters, it doesn’t know anything about
the data that you’re expecting those route parameters to contain
For example, if the template is
{controller=Home}/{action=Index}/{id?}
Both these URLs would match
/Home/List/test
/1/2/3
But we don’t have a controller named 1Controller!
We can add additional constraints to a route template that must be satisfied for a URL to be
considered a match
Constraints can be defined in a route template for a given route parameter using : (a colon)
For example, {qty:int}, means the parameter must be integer
18. Handling multiple matching actions for
a route
Often you want to match a single URL to two different action methods
One of the most common situations is when you’re submitting a form
In order to select one action over the other for a given request, you can add an
attribute
For example, the [HttpPost] attribute indicates that the method is a match for
POST requests only, and not any other HTTP methods.
Example:
[HttpPost]
public IActionResult Index(OrderModel model)
{
ViewBag.AmtDue = model.CalculateAmountDue();
return View();
}