[英]ASP.NET Core MVC Route issue
我正在尝试设置一个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值?
对于不匹配的URL(如www.test.com/fr
Core正确返回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
,否则您将无限重定向至此页面。
检查本文以获取更多详细信息: ASP.NET Core中的错误处理
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.