ASP.NET Core Routing: Generating Outgoing URLs in Views

ASP.NET Core Routing: Generating Outgoing URLs in Views

The concept of Routing is very vast and I have covered it in 6 tutorials which are:

So make sure you cover each of these one by one.

The URL Routing is also used to create Outgoing URL(links) in Views. They address an important maintenance issue because the links are created automatically based on the routes in your application. So if you change the routes, the links created in the Views are automatically changed based on the new route and you don’t have to manually change the links one by one.

Lets me show you how outgoing links are created.

First make sure you have only the below route in your application:

app.UseEndpoints(endpoints =>
{
    // Default route
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
});

Next add Razor View Imports inside the Views folder (right click on the Views folder and select Add ➤ New Item).

Razor View Imports

The View Imports lets you import the namespaces need in your Views. Import the ASP.NET Core Tag Helpers namespace because I will be using them to create links on my Views. The code which you have to add to your Razor View Imports file is given below:

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Next go to the Index View on your Home Controller and add the below code line:

<a asp-action="Check">Outgoing URL</a>

Run your application and check the link which is formed. You can do this by using the Developer Tools of your browser. So right click on the browser and select Inspect then click the link to check it’s HTML.

You will find the HTML of the Link formed is:

<a href="/Home/Check">Outgoing URL</a>

This link is formed because I used asp-action tag helper – asp-action="Check" with the anchor tag. This tag helper tells MVC the name of the action method which the anchor’s href attribute should target. Here it is the Check action method.

Note that here the ASP.NET Core targets the particular action method of the same controller where the View is. I am placing the link in the Index action of the Home controller and so the outgoing link is targeting the Check action of the Home controller.

If I want to target the Check Action of Customer Controller then I will have to also use the asp-controller tag helper in the anchor tag.

Add the below code in the Index action of the Home Controller to target the Check action of the Customer controller:

<a asp-controller="Customer" asp-action="Check">Check action of Customer Controller</a>

The link formed in this case will be:

<a href="/Customer/Check">Check action of Customer Controller</a>
Link Generation is Smart

Go to the Check action method of the Home Controller and create a link targeting the Index action method.

<a asp-action="Index">Go to Index</a>

You will find the link formed in this case contains just / and not Home/Index, see below:

<a href="/">Go to Index</a>

The reason for this is that I have specified in the route (given on the Startup.cs file) that Home is the default Controller and Index it the default action. The MVC framework is smart enough and that’s why it does not adds the Controller and Action names on the Href attribute.

You can make websites in multi-languages in ASP.NET Core. I have covered this in How to use Globalization and localization in ASP.NET Core.

Generating links from Attribute Routes

Outgoing links can also be formed based on Attribute Routing. I had an Admin controller having attribute routing as given below:

[Route("News/[controller]/USA/[action]/{id:allowedgods?}")]
public class AdminController : Controller
{
    public string Index()
    {
        // Removed for clearity
    }
     
    // ....
}

In the Index Action of Home Controller I can create a link to the Index action of the Admin controller by putting the below code:

<a asp-controller="Admin" asp-action="Index">Index Action of Admin Controller</a>

This will form the link based on Attribute Routing, and is given below:

<a href="/News/Admin/USA/Index">Index Action of Admin Controller</a>

Outgoing Links Generation when Multiple Routes are present

You can have multiple routes present in your application. When you create an outgoing link the routing system processes the routes in the order in which they are defined. It tries to match the route turn by turn. The match condition is based upon the 3 conditions:

  • 1. Every URL segment has been provided with a value.
  • 2. For the default-only variables, you must either not provide the value or provide the value that matches their default value.

    Default-only variables are those that are not present in the URL but there default value is provided. Consider an example, suppose a route which is shown below has a variable called myCountry which is the default-only variable. So for the route system to make the match you should either not provide the value for variable myCountry or provide value USA for it (which is it’s default value).

    app.UseEndpoints(endpoints =>
    {
        // Outgoing linss generations
        endpoints.MapControllerRoute(
            name: "defaultonly",
            pattern: "{controller}/{action}",
            defaults: new { myCountry = "USA" });
    });
    
  • 3. The values of segment variables should satisfy the route constraint.

Example: Link Generation when Multiple Routes are present

Suppose you have 2 routes in your application which are given below:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "stock",
        pattern: "Stock/{action}",
        defaults: new { controller = "Home" });

    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
});

Now go to your Index View of the Home Controller and add the below codes to generate links:

<a asp-action="Index">Link1</a>
<a asp-controller="Product">Link2</a>

You will find the first link is formed by the first route (stock) and the second link is formed by second route (i.e. the default one). This happens due to the 3 point of link generation which i mentioned previously.

The code for the links formed is given below:

<a href="/Stock/Index">Link1</a>
<a href="/Product">Link2</a>
Popular topic of today is what is JWT and how to use it in ASP.NET Core. I have covered it with full source codes at How to secure APIs with JWT in ASP.NET Core 3.1 [with source codes]

Passing Values to Segments Variable other than Controller and Action

Till now you have seen how to make links targeting Controllers and Action methods. What If you want to pass values to other segment variable like id ?

To do this make use of asp-route-* Tag Helper. Replace the * with the name of the segment variable like id.

Let’s create a link that passes a value for the Id segment.

Create a new controller called ProductController.cs and add an Index Action method to it.

using Microsoft.AspNetCore.Mvc;
 
namespace URLRouting.Controllers
{
    public class ProductController : Controller
    {
        public string Index(int id)
        {
            return "Id Value is: " + id;
        }
    }
} 

Now I need to link to this method from Home Controller’s Index View in such a manner that I pass a value of 100 for the Id segment.

I make use of the asp-route-* tag helper by adding the below code link to the Home Controller’s Index View:

<a asp-controller="Product" asp-action="Index" asp-route-id="100">Pass 100 to the id segment</a>

Now run your application and check the link formed, which will be –

<a href="/Product/Index/100">Pass 100 to the id segment</a>

Click the link and you will get the Id Value is: 100 displayed on the browser.

asp route tag helper
Passing Value to Query Sting

What if I pass value to a segment variable which is not described on the route ? In this case the ASP.NET Core will pass that value in Query String.

Suppose there is only 1 route present which is:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
});

Change the Index Action of the Product Controller to include a string parameter as shown:

using Microsoft.AspNetCore.Mvc;
namespace URLRouting.Controllers
{
    public class ProductController : Controller
    {
        public string Index(int id, string name)
        {
            return "Id Value is: " + id + " Name value is: " + name;
        }
    }
}

Now in the Index View of the Home Controller create a link to target the Index Action of the Product Controller as shown below:

<a asp-controller="Product" asp-action="Index" asp-route-id="100" asp-route-name="Apple">Query String</a>

Note: I added asp-route-name="Apple" to the anchor tag.

The link formed will be:

<a href="/Product/Index/100?name=Apple">Query String</a>

The link has a name value passed as query string since there is no segment variable by the name of name present in the route.

Click the link and the Index action of Product Controller is able to fetch the value of name segment. The below image shows this:

asp route query string

You can pass any number of query stings using the above method.

Generating Links from a Specific Route

You can also create the outgoing link from a specific route. Suppose there is a route in your application:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "sales",
        pattern: "sales/{controller=Home}/{action=Index}");
});

Now to create a link based on it you use the tag helper asp-route="name of the route".

That means in your View you add the below code:

<a asp-route="sales">Sales</a>

The code of the link formed is:

<a href="/sales">Sales</a> 

The asp-route attribute can be used only when the asp-controller and asp-action attributes are absent. That means the route should have the default value for the Controller and Action.

Generation only URLs i.e. The HREF of Links

The Url.Action() method is used to generate the URL i.e. the href attribute of Links.

In the Index Action of the Home Controller add the below link:

<p>URL: @Url.Action("List", "Product", new { id = 10 })</p>

You will find the generate URL as:

URL: /Product/List/10

The Url.Action() method take the following parameters:

  • 1. Controller name.
  • 2. Action name.
  • 3. Name of other segment variable.

You can also use the Url.Action() method in the u>action method using C#. See the below code that explains it.

string url = Url.Action("CustomVariable", "Home", new { id = 100 });

Adding URL Fragment (#)

The URL fragment which is denoted by a hash mark (#) is the optional last part of a URL for a document. It is typically used to identify a portion of that document. In HTML documents, the browser looks for an anchor tag with a name attribute matching the fragment.

For example, in the URL shown below, the browser finds a matching tag that has id called Printing and scrolls the page to display that section:

<a href="/Product/List#Printing">Printing</a>

To create a URL Fragment use the asp-fragment="fragment-name" tag helper. So the below code where I am creating a URL Fragment:

<a asp-controller="Product" asp-action="List" asp-fragment="Printing">
    URL Fragment
</a>

The URL formed will be:

<a href="/Product/List#Printing">URL Fragment</a>

Append Trailing slash (/) to the URLs generated by the routing system

The RouteOptions object is also used to configure URL generation so that they contain a trailing slash (/). Go to the ConfigureServices() method of the Startup.cs class and add the code – options.AppendTrailingSlash = true to the part where you configured the RouteOptions.

The code below explains it.

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<RouteOptions>(options =>
    {
        options.AppendTrailingSlash = true;
    });
    services.AddControllersWithViews();
}

Run your application and the links generated on the View, you will find all of them ending with slash (/).

Example: the URL formed for the check action method will be – http://localhost:58470/Home/Check/.

The URLs should be in Lowercase

To make all URLs in Lowercase you can add the code – options.LowercaseUrls = true inside where you are doing the configuration of RouteOptions.

The below code explains it:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<RouteOptions>(options =>
    {
        options.AppendTrailingSlash = true;
        options.LowercaseUrls = true;
    });
    services.AddControllersWithViews();
}

Now you will find the URL are all in lowercase.

Example: the URL formed for the check action method will be – http://localhost:58470/home/check/.

You can download the full codes of this tutorial from the below link:

Download

Conclusion

In this tutorial you learned to generate URLs from Routes in ASP.NET Core. Make sure to check other tutorials to.

Share this article -

yogihosting

ABOUT THE AUTHOR

This article has been written by the Technical Staff of YogiHosting. Check out other articles on "ASP.NET Core, jQuery, EF Core, SEO, jQuery, HTML" and more.