question

AspNetGuy-4752 avatar image
0 Votes"
AspNetGuy-4752 asked AspNetGuy-4752 edited

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


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.



dotnet-aspnet-core-generaldotnet-aspnet-core-razor
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

ZhiLv-MSFT avatar image
1 Vote"
ZhiLv-MSFT answered ZhiLv-MSFT edited

Hi @AspNetGuy-4752,

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.gif (239.5 KiB)
image.png (58.0 KiB)
image.png (22.0 KiB)
image.png (46.5 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

AspNetGuy-4752 avatar image
0 Votes"
AspNetGuy-4752 answered AspNetGuy-4752 edited

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.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.