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:
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).
The result as below:
[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:
We can get the same result:
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