How to prevent ASP.NET Core from removing "/en/" from the URL?

AspNetGuy 21 Reputation points
2022-09-21T03:59:21.43+00:00

I just created a new ASP.NET Core Razor Pages project on .NET Core version 3.1, when I run using the Kestrel (console hosting), it opens a Web Browser with URL: https://localhost:5001 - which is OK.

Then when I add "/en/" suffix at the end of the URL and press Enter in the address bar, the page is reloaded but "/en/" is removed from the URL. ('https://localhost:5001/en/' - turns into 'https://localhost:5001' after page reload).

But if I do the same with "/ja/" instead of "/en/" like https://localhost:5001/ja/, the page is reloaded but "/ja/" remains exactly as I want.

What I'm trying to do is to catch "/en/" from the HttpContext.Request.Path - and do some processing from my Middleware.

But since ASP.NET Core keeps removing "/en/" from the URL I can't achieve my goal. I couldn't find any useful information on the Internet about my problem.

You can easily reproduce my problem. Just create a new ASP.NET Core Razor Page project on .NET Core version 3.1. Use Kestrel instead of IIS Express. Append "/en/" at the end of the URL and press ENTER. You'll see that "/en/" is removed. At least this happens on my computer. This problem is true only with "/en/" suffixes. I tried other language codes like "/ja/", "/hk/" - they persist, they are not removed from the URL.

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,138 questions
0 comments No comments
{count} votes

Accepted answer
  1. Zhi Lv - MSFT 32,006 Reputation points Microsoft Vendor
    2022-09-21T09:25:39.85+00:00

    Hi @AspNetGuy ,

    You can easily reproduce my problem. Just create a new ASP.NET Core Razor Page project on .NET Core version 3.1. Use Kestrel instead of IIS Express. Append "/en/" at the end of the URL and press ENTER. You'll see that "/en/" is removed. At least this happens on my computer. This problem is true only with "/en/" suffixes. I tried other language codes like "/ja/", "/hk/" - they persist, they are not removed from the URL.

    According to your description, I create a sample, it keep showing the 404 error if append the /en/ or /ja/. Check the following screenshot:

    243408-1.gif

    How to prevent ASP.NET Core from removing "/en/" from the URL?

    To this issue, I think you want to add the language parameter in the URL, right?

    If that is the case, you can add constraints in the route template, for example: set the route template via @page: @page "/{language?}/", then use the @RouteData.Values["language"] to access the language parameter(you can also get the language from the request path).

    243359-image.png

    The result as below:
    243349-image.png

    [Note] By using the above method (set the route template via @page), the route only apply to current page, if you want to use this route to all pages, you have to set it on each page. Or you can refer the following method to add conventions to all pages:

    Create a CombinedPageRouteModelConvention class with the following code:

    //reference  
    //using Microsoft.AspNetCore.Mvc.ApplicationModels;  
    //using System.Collections.Generic;  
    public class CombinedPageRouteModelConvention : IPageRouteModelConvention  
    {  
        private const string BaseUrlTemplateWithoutSegment = "{language?}/";  
        private const string BaseUrlTemplateWithSegment = "{language?}/{segment?}/";  
        public void Apply(PageRouteModel model)  
        {  
            var allSelectors = new List<SelectorModel>();  
            foreach (var selector in model.Selectors)  
            {  
                //setup the route with segment  
                allSelectors.Add(CreateSelector(selector, BaseUrlTemplateWithSegment));  
    
                //setup the route without segment  
                allSelectors.Add(CreateSelector(selector, BaseUrlTemplateWithoutSegment));  
            }  
    
            //replace the default selectors with new selectors  
            model.Selectors.Clear();  
            foreach (var selector in allSelectors)  
            {  
                model.Selectors.Add(selector);  
            }  
        }  
    
        private static SelectorModel CreateSelector(SelectorModel defaultSelector, string template)  
        {  
            var fullTemplate = AttributeRouteModel.CombineTemplates(template, defaultSelector.AttributeRouteModel.Template);  
            var newSelector = new SelectorModel(defaultSelector)  
            {  
                AttributeRouteModel =  
                {  
                    Template = fullTemplate  
                }  
            };  
            return newSelector;  
        }  
    }  
    

    Then, in the startup.cs file, add Conventions:

        public void ConfigureServices(IServiceCollection services)  
        {  
            services.AddRazorPages(options =>  
            {  
                options.Conventions.Add(new CombinedPageRouteModelConvention());  
            });  
        }  
    

    After that, the razor page like this:

    243250-image.png

    We can get the same result:

    243349-image.png

    More detail information about Razor Route, see Razor Pages route and app conventions in ASP.NET Core and Razor Pages Routing.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,
    Dillion

    1 person found this answer helpful.
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. AspNetGuy 21 Reputation points
    2022-09-21T12:58:26.883+00:00

    Thank you for your detailed answer I appreciate it.
    After your answer I tried to add "/en/" on Google Chrome browser and "/en/" was not removed.

    Actually, when I start debugger in Visual Studio 2022, my website is loaded from Microsoft Edge with address: https://localhost:5001/en/.
    But /en/ then disappears. If I start New Incognito (Private) session, and put https://localhost:5001/en/, the /en/ remains only one time, all next attempts keeps removing /en/.
    If I close the Incognito (Private) session and start a new one, then again /en/ persists only one time.

    I don't know maybe this problem somehow related with browser caching or the Visual Studio debugger session.
    At least I know that it has nothing with .NET Core 3.1.

    0 comments No comments