通过QueryString设置区域性时,本地化有效,但在区域性中时则不起作用

Ash*_*ani 3 .net c# asp.net routing asp.net-core

这是我的路线:

        app.UseMvc(routes =>
        {
            routes.MapRoute(
     name: "defaultWithCulture",
     template: "{culture=fa-IR}/{controller}/{action=Index}/{id?}");
        });
Run Code Online (Sandbox Code Playgroud)

但是当我使用链接时本地化有效:

http:// localhost:1776 / fa-IR / Home / About?culture = fa-ir

但不是什么时候

http:// localhost:1776 / fa-IR / Home /关于

为什么路线中的文化不适用?

Ash*_*ani 5

SSA的答案并不能解决我的问题,但给了我一个很大的提示,最后我使它起作用了。

要做的事情是:

  1. 正如SSA所说,asp.net核心按顺序具有以下RequestCultureProviders。将使用第一个非null值。
QueryStringRequestCultureProvider
CookieRequestCultureProvider
AcceptLanguageHeaderRequestCultureProvider
Run Code Online (Sandbox Code Playgroud)

因此,我们必须更改它们的顺序并将“路由”添加为第一个:

services.Configure<RequestLocalizationOptions>(
    options =>
    {
        var supportedCultures = new List<CultureInfo>
        {
           new CultureInfo("en-US"),
           new CultureInfo("fa-IR"),
        };
        options.DefaultRequestCulture = new RequestCulture(culture: "fa-IR", uiCulture: "fa-IR");
        options.SupportedCultures = supportedCultures;
        options.SupportedUICultures = supportedCultures;
        options.RequestCultureProviders.Clear();
        options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider();
        options.RequestCultureProviders.Insert(1, new QueryStringRequestCultureProvider());
        options.RequestCultureProviders.Insert(2, new CookieRequestCultureProvider());
        options.RequestCultureProviders.Insert(3, new AcceptLanguageHeaderRequestCultureProvider());                    
        services.AddSingleton(options);
    });
Run Code Online (Sandbox Code Playgroud)

2-当执行RouteDataRequestCultureProvider Task时,RoutingData仍为null并且尚未提供值,因此它将始终返回null,因此我将其更改为如下所示,Url.Path而不是使用RoutingData:

public class RouteDataRequestCultureProvider : RequestCultureProvider
{

    public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
    {
        if (httpContext == null)
        {
            throw new ArgumentNullException(nameof(httpContext));
        }

        string culture = null;
        string uiCulture = null;
         uiCulture =  culture = httpContext.Request.Path.Value.Split('/')[1]?.ToString();
        if (culture == null)
        {
            return TaskCache<ProviderCultureResult>.DefaultCompletedTask;
        }
        var providerResultCulture = new ProviderCultureResult(culture, uiCulture);

        return Task.FromResult(providerResultCulture);
    }
} 
Run Code Online (Sandbox Code Playgroud)