Перенаправление на ту же страницу с дополнительным параметром
Я использую локализацию запроса в приложении NET Core 7 и Razor Pages:
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();
// ...
Вот несколько моих бритвенных страниц:
Index: @page "/{culture?}" Example: /pt
About: @page "/{culture?}/about" Example: /pt/about
Когдаculture
являетсяnull
или неверный. Я хочу перенаправить на ту же страницу с культурой по умолчанию.
Я пытаюсь сделать это с помощью промежуточного программного обеспечения:
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;
}
}
Когда я обращаюсь к домашней странице, например, "/", я получаю исключение в следующем:
var router = routeData.Routers[0];
Вопросы
- Как это решить?
- Могу ли я использовать перенаправление 301 из промежуточного программного обеспечения?
- Могу ли я использовать Net Core
UseRewriter
для достижения той же цели?
1 ответ
Вот целая рабочая демонстрация, которой вы можете следовать:
1.ПользовательскийIPageRouteModelConvention
чтобы отобразить маршрут, а затем не нужно изменять маршрут страницы, например@page "/{culture?}/xxx"
public class CustomCultureRouteRouteModelConvention : IPageRouteModelConvention
{
public void Apply(PageRouteModel model)
{
List<SelectorModel> selectorModels = new List<SelectorModel>();
foreach (var selector in model.Selectors.ToList())
{
var template = selector.AttributeRouteModel.Template;
selectorModels.Add(new SelectorModel()
{
AttributeRouteModel = new AttributeRouteModel
{
Template = "/{culture}" + "/" + template
}
});
}
foreach (var m in selectorModels)
{
model.Selectors.Add(m);
}
}
}
2. Добавьте соглашения об этой странице в Program.cs.
builder.Services.AddRazorPages().AddRazorPagesOptions(opts =>
{
opts.Conventions.Add(new CustomCultureRouteRouteModelConvention()); //add this...
});
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
builder.Services.Configure<RequestLocalizationOptions>(
opt =>
{
var supportCulteres = new List<CultureInfo>
{
new CultureInfo("pt"),
new CultureInfo("fr")
};
opt.DefaultRequestCulture = new RequestCulture("pt");
opt.SupportedCultures = supportCulteres;
opt.SupportedUICultures = supportCulteres;
opt.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider()); //add this...
});
3. Порядок промежуточного программного обеспечения
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
//app.UseRequestLocalization();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseRequestLocalization(); //be sure add here......
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Результат: