0

私は例えば、複数の国のための多言語をサポートするために、セットアップにASP.NET MVCのコアサイトをしようとしている:ASP.NET MVCコアルート問題

  • www.test.com/au/en(オーストラリア、英語)
  • www.test.com/au/deドイツ(オーストラリア)

は、現在のユーザーのための培養を設定するには、私はこのコードを見つけ

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

私はこのようになりますRequestCultureProvider作成:次にStartup.csで、設定では、私はその後、

// setup routes 
app.UseGetRoutesMiddleware(GetRoutes); 
// add localization 
var supportedCultures = new List<CultureInfo>() { 
       new CultureInfo("en"), 
       new CultureInfo("de"), 
      }; 

var requestLocalizationOptions = new RequestLocalizationOptions 
{ 
    DefaultRequestCulture = new RequestCulture(supportedCultures.First()), 
    SupportedCultures = supportedCultures, 
    SupportedUICultures = supportedCultures, 
}; 
requestLocalizationOptions.RequestCultureProviders.Clear(); 
requestLocalizationOptions.RequestCultureProviders.Add(
    new RequestCultureProvider() 
); 
app.UseRequestLocalization(requestLocalizationOptions); 
を持って

private readonly Action<IRouteBuilder> GetRoutes = 
    routes => 
    { 
     routes.MapRoute(name: "Default", 
         template: "{area}/{language}/{controller}/{action}", 
         defaults: new { area = "au", language = "en", controller = "home", action = "Index" }, 
         constraints: new { area = new RequiredRouteConstraint(), language = new RegexRouteConstraint("^(en|de)$") }); 
    }; 

:私はこの方法を持って、セットアップルートに

public class RequestCultureProvider : IRequestCultureProvider 
{ 
    public Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext) 
    { 
     if (httpContext.GetRouteValue("language") == null) 
     { 
      return Task.FromResult(new ProviderCultureResult("en", "en")); 
     } 
     var langauge = httpContext.GetRouteValue("language").ToString().ToLower(); 
     return Task.FromResult(new ProviderCultureResult(langauge, langauge)); 
    } 
} 

私はそれが適切かどうかはわかりませんが、もっと整理された方法でレイアウトをレイアウトするには、次のようなCultureViewExpanderを設定してください:

public class CultureViewExpander : IViewLocationExpander 
{ 
    public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations) 
    { 
     return viewLocations.Select(s => s.Replace("%1", CultureInfo.CurrentUICulture.TwoLetterISOLanguageName)); 
    } 

    public void PopulateValues(ViewLocationExpanderContext context) 
    { 
     context.Values.Add("Language", CultureInfo.CurrentUICulture.TwoLetterISOLanguageName); 
    } 
} 

と私は単純に、

services.Configure<RazorViewEngineOptions>(o => 
{ 
    o.ViewLocationExpanders.Add(new CultureViewExpander()); 

    // {0} for the action 
    // {1} for the controller 
    // {2} for the area 
    // %1 for language 
    o.ViewLocationFormats.Clear(); 
    o.ViewLocationFormats.Add("/Views/Shared/{0}" + RazorViewEngine.ViewExtension); 

    o.AreaViewLocationFormats.Clear(); 
    o.AreaViewLocationFormats.Insert(0, "/Areas/{2}/Views/{1}/%1/{0}" + RazorViewEngine.ViewExtension); 
}); 

サポートされる言語が正常に動作として、私はwww.test.com/au/frに移動すると、それはConfigureServicesで、Startup.csに実装されています空白の画面が表示されますが、404を返す必要があります。無効なルート値に対して404を返すにはどうすればよいですか?

+0

あなたはUIの文化に 'language'をマッピングするコードの一部を示してもらえますか? –

答えて

0

ASP.NETコアは、www.test.com/frのように一致しないURLに対して正しく404エラーを返します。このような対応方法はブラウザに任されています。あなたが説明したように、Firefoxは単に空白のページを表示します。エラーの説明とIE、ChromeとOperaのショーのページのように:エラーコードが返されるべきとき

enter image description here

あなたはASP.NETコアの動作をカスタマイズすることができます。あなたはまた、要求失敗した場合にカスタムエラーページにユーザーをリダイレクトすることができ

app.UseStatusCodePages("text/plain", "Status code page, status code: {0}"); 

:あなたはアプリケーションの設定にUseStatusCodePagesを追加することで、単純なテキストメッセージを使用することができますいずれか

app.UseStatusCodePagesWithRedirects("/error/{0}"); 

は気をつけてください/error/404正しく解決されますそうでなければ、このページへの無限のリダイレクトを取得します。

詳細については、この記事をチェックしてください:Error Handling in ASP.NET Core