Search code examples
c#asp.net-coreasp.net-core-mvc-2.0razor-pages

ASP.NET Core RazorPages to force AnchorTagHelper (asp-page) to use lowercase routes


I am using RazorPages in ASP.NET Core v2.0, and I was wondering if anyone knows how to force the AnchorTagHelper to use lowercase?

For example, in my .cshtml mark-up, I would have the following anchor tag using the asp-page tag helper:

<a asp-page="/contact-us">Contact Us</a>

The output that I am looking for

// i want this 
<a href="/contact-us">Contact Us</a>

// i get this 
<a href="/Contact-us">Contact Us</a>

To give it more context to why this is important to my web app, please imagine a long url like what you would see at stackoverflow.com

https://stackoverflow.com/questions/anchortaghelper-asp-page-to-use-lowercase

                       -- VS --

https://stackoverflow.com/Questions/Anchortaghelper-asp-page-to-use-lowercase

Any help would be appreciated!


I have looked at these other references but no luck:


Solution

  • The url helper that will generate the target link will use the metadata that is being generated for routes. For razor pages, this uses the exact file path to identify the route.

    Starting with ASP.NET Core 2.1, you will likely be able to adjust the route just like MVC routes using the Route attribute. At least it’s planned for the 2.1 release.

    Until then, you will have to configure specific routes for your pages in the ConfigureServices method:

    services.AddMvc()
        .AddRazorPagesOptions(options =>
        {
            options.Conventions.AddPageRoute("/ContactUs", "contact-us");
        });
    

    This will keep the existing route available for use, so if you do not want that, you will need to replace the route selector for this page. There is no built-in way to do this, but it’s not too difficult to do it when you know what to do.

    To avoid code duplication and to make everything nicer, we’ll just create a ReplacePageRoute extension method, that basically matches the usage of the AddPageRoute above:

    services.AddMvc()
        .AddRazorPagesOptions(options => {
            options.Conventions.ReplacePageRoute("/Contact", "contact-us");
        });
    

    The implementation of that method is directly inspired by that AddPageRoute:

    public static PageConventionCollection ReplacePageRoute(this PageConventionCollection conventions, string pageName, string route)
    {
        if (conventions == null)
            throw new ArgumentNullException(nameof(conventions));
        if (string.IsNullOrEmpty(pageName))
            throw new ArgumentNullException(nameof(pageName));
        if (route == null)
            throw new ArgumentNullException(nameof(route));
    
        conventions.AddPageRouteModelConvention(pageName, model =>
        {
            // clear all existing selectors
            model.Selectors.Clear();
    
            // add a single selector for the new route
            model.Selectors.Add(new SelectorModel
            {
                AttributeRouteModel = new AttributeRouteModel
                {
                    Template = route,
                }
            });
        });
    
        return conventions;
    }