I am using Request Localization in a NET Core 7 and Razor Pages application:
builder.Services.AddRazorPages();
builder.Services.Configure<RequestLocalizationOptions>(options => {
options.DefaultRequestCulture = new RequestCulture("pt");
options.SupportedCultures = new List<CultureInfo> { new CultureInfo("en"), new CultureInfo("pt") };
options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider {
RouteDataStringKey = "culture",
UIRouteDataStringKey = "culture",
Options = options
});
});
WebApplication application = builder.Build();
application.UseRouting();
application.MapRazorPages();
application.UseRequestLocalization();
// ...
A few of my razor pages are:
Index: @page "/{culture?}" Example: /pt
About: @page "/{culture?}/about" Example: /pt/about
When the culture
is null
or invalid I want to redirect to same page with default culture.
I am trying to do this using a middleware:
public class RedirectUnsupportedCulturesMiddleware {
private readonly RequestDelegate _next;
private readonly string _routeDataStringKey;
public RedirectUnsupportedCulturesMiddleware(
RequestDelegate next,
IOptions<RequestLocalizationOptions> monitor) {
RequestLocalizationOptions options = monitor.Value;
_next = next;
var provider = options.RequestCultureProviders
.Select(x => x as RouteDataRequestCultureProvider)
.Where(x => x != null)
.FirstOrDefault();
_routeDataStringKey = provider.RouteDataStringKey;
}
public async Task Invoke(HttpContext context) {
var requestedCulture = context.GetRouteValue(_routeDataStringKey)?.ToString();
var cultureFeature = context.Features.Get<IRequestCultureFeature>();
var actualCulture = cultureFeature?.RequestCulture.Culture.Name;
if (string.IsNullOrEmpty(requestedCulture) ||
!string.Equals(requestedCulture, actualCulture, StringComparison.OrdinalIgnoreCase)) {
var newCulturedPath = GetNewPath(context, actualCulture);
context.Response.Redirect(newCulturedPath);
return;
}
await _next.Invoke(context);
}
private string GetNewPath(HttpContext context, string newCulture) {
var routeData = context.GetRouteData();
var router = routeData.Routers[0];
var virtualPathContext = new VirtualPathContext(
context,
routeData.Values,
new RouteValueDictionary { { _routeDataStringKey, newCulture } });
return router.GetVirtualPath(virtualPathContext).VirtualPath;
}
}
When I access the home page, e.g "/", I get an exception in the following:
var router = routeData.Routers[0];
Questions
- How to solve this?
- Can I use a 301 redirect from thee middleware?
- Can I use the Net Core
UseRewriter
to accomplish the same objective?
Here is a whole working demo you could follow:
1.Custom
IPageRouteModelConvention
to map the route and then no need modify page route like@page "/{culture?}/xxx"
2.Add this page conventions in Program.cs
3.The order of the middleware
Result: