Razor Pages: Urls generated by built-in taghelpers do not honor PageRouteModelConvention
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 290
Description
### Describe the bug
In a project that utilizes Razor Pages and request localization in conjunction with an `IPageRouteModelConvention`, Urls generated through standard TagHelpers for anchors or forms do not honor routing conventions and route values.
### To Reproduce
**Current route values (page url is `/de`)**
- Page: /Index
- culture: de
**Markup:**
`Search`
**Expected Result:**
`Search`
**Actual Result:**
`Search`
There's a workaround but it is quite ugly:
`Search`
**Startup.cs:**
```c#
public class Startup
{
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
Configuration = configuration;
Env = env;
var builder = new ConfigurationBuilder()
.SetBasePath(Environment.CurrentDirectory)
.AddJsonFile("appsettings.json", optional: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
if (env.IsDevelopment())
builder.AddUserSecrets();
Configuration = builder.Build();
}
public IConfiguration Configuration { get; }
public IWebHostEnvironment Env { get; }
public static RequestCulture DefaultRequestCulture = new RequestCulture("en-US", "en-US");
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.AddSingleton(Configuration);
services.AddRazorPages(options =>
{
options.Conventions.Add(new CultureTemplateRouteModelConvention());
}).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.Configure(options =>
{
options.DefaultRequestCulture = DefaultRequestCulture;
options.SupportedCultures = AppConstants.SupportedCultures;
options.SupportedUICultures = AppConstants.SupportedCultures;
options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider { Options = options });
});
services.AddRouting(options =>
{
options.LowercaseUrls = true;
});
services.AddOptions();
services.AddLogging();
services.AddSingleton();
services.AddSingleton(Configuration);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
Container = app.ApplicationServices.GetAutofacRoot();
app.UseStaticFiles();
app.UseRouting();
app.UseRequestLocalization();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
}
}
```
**CultureTemplateRouteModelConvention.cs:**
```c#
public class CultureTemplateRouteModelConvention : IPageRouteModelConvention
{
public void Apply(PageRouteModel model)
{
var selectorCount = model.Selectors.Count;
for (var i = 0; i < selectorCount; i++)
{
var selector = model.Selectors[i];
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = -1,
Template = AttributeRouteModel.CombineTemplates(
"{culture?}", selector.AttributeRouteModel.Template),
}
});
}
}
}
```
### Further technical details
- ASP.NET Core 3.0
- VS 2019
Contributor guide
Assessment
This issue has not been assessed yet.