2016-07-21 23 views
19

私は新しいAsp.Netコアmvc​​アプリケーションでwokringです。 URLから現在のアプリカルチャーを設定するカスタム制約付きのルートを定義しました。私はこのようになりますカスタムIRequestCultureProviderを作成することによって、私のアプリのローカライズを管理しようとしている:Asp.NetコアURLからRouteData値を取得

public class MyCustomRequestCultureProvider : IRequestCultureProvider 
    { 
     public Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext) 
     { 
      var language= httpContext.GetRouteValue("language"); 

      var result = new ProviderCultureResult(language, language); 
      return Task.FromResult(result); 
     } 
    } 

マイMyCustomRequestCultureProvider okですすべての要求、上でヒットしました。私の問題は、MVCパイプラインで、私のプロバイダのDetermineProviderCultureResultメソッドがルーティングプロセスの前にヒットしているので、httpContext.GetRouteValue("language")は常にnullを返します。

MVCの以前のバージョンでは、私は新しいframewrok右に同じことを行うための方法を見つけることができません手動でこの

var wrapper = new HttpContextWrapper(HttpContext.Current); 
var routeData = RouteTable.Routes.GetRouteData(wrapper); 
var language = routeData.GetValue("language") 

を行うことによって、ルーティングプロセスを通じて、私のURLを処理する可能性について持っていたが今。また、ルートデータを使用して私のlangugaeを見つけ出し、言語を見つけるためのいくつかの文字列関数を使ってURL文字列を分析したい

+0

この[質問とその答え(http://stackoverflow.com/questions/35829426/optionally-override-request-culture-via-url-route-inを定義します-an-asp-net-core-1-0-applica/35970676#35970676)助けてくれるかもしれない –

+0

@nboisvertこの問題を解決できますか? – SherleyDev

+0

@SherleyDevは私の答えを見る –

答えて

7

これを行う簡単な方法はなく、ASP.Netチームはこの機能をまだ実装していません。 IRoutingFeatureは、MVCがリクエストを完了した後でのみ利用可能です。

私はあなたにはうってつけのソリューションをまとめました。これにより、あなたはUseMvc()に渡す経路と、IRoutingFeatureを設定するためのすべての属性ルーティングを設定します。それが完了したら、httpContext.GetRouteValue("language");でそのクラスにアクセスできます。

private readonly Action<IRouteBuilder> GetRoutes = 
    routes => 
    { 
     routes.MapRoute(
      name: "custom", 
      template: "{language=fr-FR}/{controller=Home}/{action=Index}/{id?}"); 

     routes.MapRoute(
      name: "default", 
      template: "{controller=Home}/{action=Index}/{id?}"); 
    }; 

が新たなミドルウェアを追加します。Startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    // setup routes 
    app.UseGetRoutesMiddleware(GetRoutes); 

    // add localization 
    var requestLocalizationOptions = new RequestLocalizationOptions 
    { 
     DefaultRequestCulture = new RequestCulture("en-US") 
    }; 
    requestLocalizationOptions.RequestCultureProviders.Clear(); 
    requestLocalizationOptions.RequestCultureProviders.Add(
     new MyCustomRequestCultureProvider() 
    ); 
    app.UseRequestLocalization(requestLocalizationOptions); 

    // add mvc 
    app.UseMvc(GetRoutes); 
} 

は(再利用性のための)代理人へのルート、同じファイル/クラスを移動しました

public static class GetRoutesMiddlewareExtensions { public static IApplicationBuilder UseGetRoutesMiddleware(this IApplicationBuilder app, Action<IRouteBuilder> configureRoutes) { if (app == null) { throw new ArgumentNullException(nameof(app)); } var routes = new RouteBuilder(app) { DefaultHandler = app.ApplicationServices.GetRequiredService<MvcRouteHandler>(), }; configureRoutes(routes); routes.Routes.Insert(0, AttributeRouting.CreateAttributeMegaRoute(app.ApplicationServices)); var router = routes.Build(); return app.UseMiddleware<GetRoutesMiddleware>(router); } } public class GetRoutesMiddleware { private readonly RequestDelegate next; private readonly IRouter _router; public GetRoutesMiddleware(RequestDelegate next, IRouter router) { this.next = next; _router = router; } public async Task Invoke(HttpContext httpContext) { var context = new RouteContext(httpContext); context.RouteData.Routers.Add(_router); await _router.RouteAsync(context); if (context.Handler != null) { httpContext.Features[typeof (IRoutingFeature)] = new RoutingFeature() { RouteData = context.RouteData, }; } // proceed to next... await next(httpContext); } } 

あなたはOだけでなく、このクラス...

public class RoutingFeature : IRoutingFeature 
{ 
    public RouteData RouteData { get; set; } 
} 
+0

これは私のためにうまくいった、私はgeにする必要があった – Ben

+0

5分のためのコメントを編集できることは痛みである!これは私が言いたいことです:他のミドルウェアのパラメータにアクセスする必要がありました。 5 *再び使用する – Ben

関連する問題