Asp.net .Net Core 3.1 Razor页面:自动更正到区域性
我试图用MS Docs实现类似的行为 例如,如果您访问https://docs.microsoft.com/,您将被重定向到您的文化,在我的情况下,我将被自动重定向到https://docs.microsoft.com/en gb/ 如果您访问内部页面时没有URL中的区域性,则内部页面也是如此 例如,通过访问: https://docs.microsoft.com/aspnet/core/razor-pages/?view=aspnetcore-3.1和选项卡=visual studio 它将自动将您重定向到: https://docs.microsoft.com/en gb/aspnet/core/razor pages/?view=aspnetcore-3.1&tabs=visual studio 我有一个小的演示应用程序,在那里我对.NETCore3.1和Razor页面进行本地化实验 我已经设置了Asp.net .Net Core 3.1 Razor页面:自动更正到区域性,asp.net,asp.net-core,razor,.net-core,Asp.net,Asp.net Core,Razor,.net Core,我试图用MS Docs实现类似的行为 例如,如果您访问https://docs.microsoft.com/,您将被重定向到您的文化,在我的情况下,我将被自动重定向到https://docs.microsoft.com/en gb/ 如果您访问内部页面时没有URL中的区域性,则内部页面也是如此 例如,通过访问: https://docs.microsoft.com/aspnet/core/razor-pages/?view=aspnetcore-3.1和选项卡=visual studio 它将自
选项.约定
,并且创建了CustomCultureRouteModelConvention
类,但是我对.NET Core非常熟悉,我有点执着于如何实现上述功能
提前谢谢大家 如ms文档中所述;每个本地化请求初始化一个RequestCultureProvider
列表,并按以下顺序枚举:
http://localhost:1234/Index?culture=en
要确保其工作方式,请删除区域性cookie并通过将所需语言移到顶部来更改浏览器语言首选项,您将看到该语言是根据浏览器首选项选择的。您应该使用现有的重写中间件执行重定向: 在最简单的形式中,如果重写中间件在URL路径的开头没有看到区域设置模式,您可以告诉它重定向
new RewriteOptions().AddRedirect(“^([a-z]{2}-[a-z]{2})”,“en-US/$1”)
(未测试regex)或使用更详细的规则执行完整的重定向类,并将其重定向到您想要重定向的语言环境。该aspnet文档引用中的示例,可用于了解自定义重定向规则的工作原理。为了适应您的案例作为概念证明,我重用了您现有的重定向UnsupportedCulture
中的大部分逻辑:
public class RedirectUnsupportedCultures : IRule
{
private readonly string _extension;
private readonly PathString _newPath;
private IList<CultureInfo> _cultureItems;
private string _cultureRouteKey;
public RedirectUnsupportedCultures(IOptions<RequestLocalizationOptions> options)
{
RouteDataRequestCultureProvider provider = options.Value.RequestCultureProviders
.OfType<RouteDataRequestCultureProvider>()
.First();
_cultureItems = options.Value.SupportedUICultures;
_cultureRouteKey = provider.RouteDataStringKey;
}
public void ApplyRule(RewriteContext rewriteContext)
{
// do not redirect static assets and do not redirect from a controller that is meant to set the locale
// similar to how you would not restrict a guest user from login form on public site.
if (rewriteContext.HttpContext.Request.Path.Value.EndsWith(".ico") ||
rewriteContext.HttpContext.Request.Path.Value.Contains("change-culture"))
{
return;
}
IRequestCultureFeature cultureFeature = rewriteContext.HttpContext.Features.Get<IRequestCultureFeature>();
string actualCulture = cultureFeature?.RequestCulture.Culture.Name;
string requestedCulture = rewriteContext.HttpContext.GetRouteValue(_cultureRouteKey)?.ToString();
// Here you can add more rules to redirect based on maybe cookie setting, or even language options saved in database user profile
if(string.IsNullOrEmpty(requestedCulture) || _cultureItems.All(x => x.Name != requestedCulture)
&& !string.Equals(requestedCulture, actualCulture, StringComparison.OrdinalIgnoreCase))
{
string localizedPath = $"/{actualCulture}{rewriteContext.HttpContext.Request.Path.Value}";
HttpResponse response = rewriteContext.HttpContext.Response;
response.StatusCode = StatusCodes.Status301MovedPermanently;
rewriteContext.Result = RuleResult.EndResponse;
// preserve query part parameters of the URL (?parameters) if there were any
response.Headers[HeaderNames.Location] =
localizedPath + rewriteContext.HttpContext.Request.QueryString;
}
}
改进:
在使用上述代码后,我遇到了一个bug,如果应用程序不支持区域性,重定向将以无限的区域性路径结束。例如,如果我支持区域性en
(默认)和gr
,如果不是/en/foobar
或/gr/foobar
,我将编写/fr/foobar
,我将得到/en/fr/foobar
,然后是/en/en/fr/foobar
等等
我添加了private readonly LinkGenerator\u LinkGenerator代码>到类,我在构造函数中初始化它。我删除了那行stringlocalizedpath=$“/{actualCulture}{rewriteContext.HttpContext.Request.Path.Value}”代码>该行后面的代码如下所示:
rewriteContext.HttpContext.GetRouteData().Values[\u cultureRouteKey]=actualCulture;
HttpResponse response=rewriteContext.HttpContext.response;
response.StatusCode=StatusCodes.Status301永久移动;
rewriteContext.Result=RuleResult.EndResponse;
//保留URL的查询部分参数(?参数)(如果有)
响应.标题[标题.位置]=
_linkGenerator.GetPathByAction(
重写context.HttpContext,
值:rewriteContext.HttpContext.GetRouteData().values
)
+rewriteContext.HttpContext.Request.QueryString;
感谢您的回复,我的问题不是检测区域设置,而是如何正确重定向用户,正如我在文章中所描述的。例如,如果你检查我的演示应用程序,我有两种文化,一种是en-US,另一种是en-GB。访问时,在en US语言环境中,您将看到“欢迎朋友!”消息,在en GB中,您将看到“欢迎小伙子!”。我尝试的是在访问时自动重定向到/{locale}。另外,如果您访问/即将自动重定向到/{locale}/about等。。。我有点挣扎,因为我对.net World相当陌生。我已经检查了你的应用程序,它正在按预期工作。只是不设置区域性cookie,默认情况下它将使用浏览器本地。是的,通过删除cookie,它会检测到浏览器区域设置,我知道,但它不会自动重定向,它会在您的端进行吗?例如,当您访问时,它会自动将您重定向到?非常感谢@alex tech的回复!这确实是我想要的:)@alex tech。。。谢谢你的方法。不过只有一个问题。。如果我们最初的请求是一篇博文,是否有可能在我们的重写位置保留。。。假设我有一个URL/search,它正在将其转换为/en/search,但是如果/search是一个POST请求,那么/en/search在随后的点击中会变成一个GET…@StackAddict看看这里:
// Attempt to make auto-redirect to culture if it is not exist in the url
RewriteOptions rewriter = new RewriteOptions();
rewriter.Add(new RedirectUnsupportedCultures(app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>()));
app.UseRewriter(rewriter);