我尝试设置ASP.NET Core MVC网站以支持多个国家/地区的多语言,例如:
要为当前用户设置文化,我找到了此代码
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:
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));
}
}
要设置路线我有这个方法:
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)$") });
};
然后在Startup.cs中,在Configure中,我有
// 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);
我不确定它是否相关,但是为了更有条理地布置我的观点,我设置了一个看起来像这样的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);
}
}
它在Startup.cs中实现,在ConfigureServices中实现为
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时,我只是得到一个空白的屏幕,但我需要它返回404.我怎么能得到它返回404为无效的路线值?
答案 0 :(得分:0)
ASP.NET Core正确地为不匹配的网址www.test.com/fr
返回404错误。它取决于浏览器如何处理这样的响应。 Firefox只显示您描述的空白页面。 IE,Chrome和Opera显示页面,其中包含错误说明,如:
您应该在返回错误代码时自定义ASP.NET Core行为。您可以通过将UseStatusCodePages
添加到应用程序配置来使用简单的文本消息:
app.UseStatusCodePages("text/plain", "Status code page, status code: {0}");
如果请求失败,您还可以将用户重定向到自定义错误页面:
app.UseStatusCodePagesWithRedirects("/error/{0}");
确保路径/error/404
已正确解析,否则您将无限重定向到此页面。
查看此文章了解更多详情:Error Handling in ASP.NET Core