c# - 基于端点的路由.net core 3.1中缺少端点
问题描述
我正在使用由 WebApi 和 MVC 路由组成的多租户 .net 核心 Web 应用程序。对于正常行为的应用程序应该转到后备控制器,使用外部帮助将决定哪个主/租户控制器将被执行重定向。但有时应用程序拒绝找到适当的后备动作。经过一番调查,我发现在这些时刻,并非所有端点都在注册。经过两天的搜索,我发现这些问题大部分都影响了Razor,但没有一个适用于MVC/WebApi。我开始认为这是由 .MapWhen() 的第二个分支引起的,但未得到证实。
因此,对于解决此问题的任何帮助,我将不胜感激。还将我当前的路由配置附在下面:
配置服务方法:
services.AddControllersWithViews(options =>
{
options.Filters.Add(typeof(ReverseProxyFilter));
options.Conventions.Add(new ApiExplorerGroupPerVersionConvention());
})
.AddRazorRuntimeCompilation()
.AddApplicationPart(typeof(EmailNamespace).Assembly)
.AddViewLocalization()
.SetCompatibilityVersion(CompatibilityVersion.Latest)
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
options.SerializerSettings.DateParseHandling = DateParseHandling.DateTimeOffset;
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
})
.AddControllersAsServices();
services.AddRazorPages();
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedProto;
});
services.Configure<RouteOptions>(routeOptions =>
{
routeOptions.ConstraintMap.Add("master", typeof(MasterRouteConstraint));
routeOptions.ConstraintMap.Add("tenant", typeof(TenantRouteConstraint));
});
配置方法:
app.UseMiddleware<TenantFilterMiddleware>();
app.UseHttpStatusCodeExceptionMiddleware();
app.UseResponseCaching();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<WebsocketsHub>("/hubs");
endpoints.MapControllers();
endpoints.MapRazorPages();
});
app.MapWhen(
context => !context.Request.Path.Value.StartsWith("/api"),
builder =>
{
builder.UseRouting();
builder.UseEndpoints(endpoints =>
{
endpoints.MapFallbackToController("Index", "Fallback");
});
});
异常示例:
An unhandled exception occurred while processing the request.
InvalidOperationException: Cannot find the fallback endpoint specified by route values:
{
action: Index,
controller: Fallback,
area:
}.
Microsoft.AspNetCore.Mvc.Routing.DynamicControllerEndpointMatcherPolicy.ApplyAsync(HttpContext HttpContext, CandidateSet candidates)
解决方案
经过两天的尝试和研究,解决方案像往常一样简单。解决这个问题的方法是稍微重写路由管道。据我所知,微软路由系统非常喜欢将分支放在默认分支之前而不是之后,在这种情况下,所有系统行为在 100% 的情况下都按预期开始工作。
所以不要这样:
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<WebsocketsHub>("/hubs");
endpoints.MapControllers();
endpoints.MapRazorPages();
});
app.MapWhen(
context => !context.Request.Path.Value.StartsWith("/api"),
builder =>
{
builder.UseRouting();
builder.UseEndpoints(endpoints =>
{
endpoints.MapFallbackToController("Index", "Fallback");
});
});
现在我有这个:
app.MapWhen(context => !context.Request.Path.Value.StartsWith("/api"), ConfigureApiPipeline);
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseSession();
app.UseEndpoints(MapBasicEndpoints);
函数ConfigureApiPipeline()
如下所示:
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseSession();
app.UseEndpoints(endpoints =>
{
MapBasicEndpoints(endpoints);
endpoints.MapHealthChecks(SystemLivenessCheck.Path, new HealthCheckOptions()
{
AllowCachingResponses = false,
ResultStatusCodes = new Dictionary<HealthStatus, int>
{
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Degraded] = StatusCodes.Status503ServiceUnavailable,
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable,
},
});
endpoints.MapFallbackToController("Index", "Fallback");
});
并且MapBasicEndpoints
是:
private static void MapBasicEndpoints(IEndpointRouteBuilder endpoints)
{
endpoints.MapHub<WebsocketsHub>("/hubs");
endpoints.MapControllers();
}
推荐阅读
- node.js - “RichEmbed 描述不得超过 2048 个字符”
- regex - Bash 检查文件匹配正则表达式是否存在并将文件名分配给变量
- java - Spark 核心多列分组方式
- java - 我第一次尝试学习方法,但是在尝试编译时出现错误
- rust - 我应该使用什么特征来从文件、TCP 连接、简单字符串中读取字节流......?
- javascript - 尝试创建新的 React 应用程序时出错
- google-apps-script - 通过 Google 表格中的 Appscript 访问和恢复到特定(最好命名)修订
- python - 在 Visual Studio Code 中调试返回 [Errno 2] No such file or directory,但是从 cmd 运行时工作正常
- azure - 添加物联网设备时无法创建对称密钥
- angular - 我可以创建一个有角度的库,但这取决于另一个 NPM 本地库