Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当通过QueryString设置区域性时,本地化工作,但当区域性处于路由中时,本地化工作不起作用_C#_Asp.net_.net_Asp.net Core_Routing - Fatal编程技术网

C# 当通过QueryString设置区域性时,本地化工作,但当区域性处于路由中时,本地化工作不起作用

C# 当通过QueryString设置区域性时,本地化工作,但当区域性处于路由中时,本地化工作不起作用,c#,asp.net,.net,asp.net-core,routing,C#,Asp.net,.net,Asp.net Core,Routing,这是我的路线: app.UseMvc(routes => { routes.MapRoute( name: "defaultWithCulture", template: "{culture=fa-IR}/{controller}/{action=Index}/{id?}"); }); 但当我使用链接时,本地化是有效的: 但不是什么时候 为什么路线中的文化不适用 据我所知,asp.net核心按

这是我的路线:

        app.UseMvc(routes =>
        {
            routes.MapRoute(
     name: "defaultWithCulture",
     template: "{culture=fa-IR}/{controller}/{action=Index}/{id?}");
        });
但当我使用链接时,本地化是有效的:

但不是什么时候


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

据我所知,asp.net核心按顺序有以下RequestCultureProviders。将使用第一个非null

您需要添加以支持路由数据中的区域性

例如:


SSA的回答并没有解决我的问题,但给了我一个很大的线索,最后我让它发挥作用

要做的是:

  • 正如SSA所说,asp.net核心有以下RequestCultureProviders。将使用第一个非null
  • 因此,我们必须更改它们的顺序,并将路由添加为第一个:

    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);
        });
    

    您的路由模板应该是
    模板:“{culture}/{controller}/{action=Index}/{id?}”)。如何使用URL中的值来设置当前线程的区域性?@ChetanRanpariya我没有设置它。路由本身不应该这样做吗?您想要的行为在asp.net mvc core中是现成的。您可能需要编写一个操作筛选器,该筛选器将从URL中检索区域性的路由数据值,并将其设置为当前线程。@ChetanRanpariya能否将其添加为答案并演示如何操作?我以前回答过类似的问题。请参阅,如果您在该方法中遇到任何问题,请告诉我。我在多个地方看到了此解决方案,但问题是,对于我来说,我得到的错误是找不到类型或命名空间名称“RouteDataRequestCultureProvider”(您是否缺少using指令或程序集引用?)
    ,我找不到任何可以解决此问题的名称空间。你知道我该怎么解决吗?你需要获得Microsoft.AspNetCore.Localization.Routing包。“Microsoft.AspNetCore.Localization.Routing”:“1.1.0”我和您有相同的问题(RoutingData为空)。它是一只虫子吗?@FernandoMondo不,它不是一只虫子。这是因为本地化中间件在MVC路由器之前运行,所以它还没有对其进行解析。@MarkSzabo我认为这是一种bug或错误实现。因为这是标准的aspnet库,它不工作。谢谢你对这个话题的指导。我将创建自己的RequestCultureProvider类。那么,如果在路由之后没有调用RoutedDataRequestCultureProvider,它有什么用呢?我的意思是-我可以通过手动解析路径来使用变通方法,但我有复杂的路由规则。
    public void ConfigureServices(IServiceCollection services)  
    {
        // Add framework services.
        services.AddMvc();
    
        var supportedCultures = new[]
        {
            new CultureInfo("en-US"),
            new CultureInfo("en-GB"),
            new CultureInfo("de"),
            new CultureInfo("fr-FR"),
        };
    
        var options = new RequestLocalizationOptions()
        {
            DefaultRequestCulture = new RequestCulture(culture: "en-GB", uiCulture: "en-GB"),
            SupportedCultures = supportedCultures,
            SupportedUICultures = supportedCultures
        };
        options.RequestCultureProviders = new[] 
        { 
             new RouteDataRequestCultureProvider() { Options = options } 
        };
    
        services.AddSingleton(options);
    }
    
    QueryStringRequestCultureProvider
    CookieRequestCultureProvider
    AcceptLanguageHeaderRequestCultureProvider
    
    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);
        });
    
    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);
        }
    }