【发布时间】:2020-07-06 13:20:26
【问题描述】:
我正在使用由 WebApi 和 MVC 路由组成的多租户 .net 核心 Web 应用程序。对于正常行为的应用程序应该转到后备控制器,使用外部帮助将决定哪个主/租户控制器将被执行重定向。但有时应用程序拒绝找到适当的后备动作。经过一番调查,我发现在这些时刻,并非所有端点都在注册。经过两天的搜索,我发现这些问题大部分都影响了Razor,但没有一个适用于MVC/WebApi。我开始认为这是由于 .MapWhen() 有第二个分支但未确认。
因此,对于解决此问题的任何帮助,我将不胜感激。还将我当前的路由配置附在下面:
ConfigureServices 方法:
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)
【问题讨论】:
-
注册是什么意思? Internet 中使用的是什么协议?是 TCP 吗?我将首先在控制器上使用 from cmd.exe >Netstat -a 并按端口号检查侦听器和连接。您只会在已连接的客户端上发送数据。因此,首先要找出哪些客户端已连接,并与已注册的客户端进行比较。我对 MVC 不太熟悉,但对 Internet 路由非常了解。我们需要确定 URL 是否正确。
-
@jdweng,通过注册我的意思是:应用程序启动后,应用程序将拥有端点字典。当一切都正确启动时,这个字典有大约 480 个不同类型的端点,但有时,它只有 240 个端点,所有这些端点都是相同的类型。我相信 URL 是正确的,因为请求 100% 的时间到达服务器,所以我假设这是更多与配置相关的问题,而不是基本的互联网路由问题。
-
服务器下线时端点如何被移除?代码如何确定何时应该使用回退端点?您是否查看过诸如wireshark 或fiddler 之类的嗅探器结果?我假设可以看到连接到控制器(可能是 ARP)的尝试,并且当没有响应时,会再次尝试回退。一台机器有一个 ARP 表,你可以从 cmd.exe >ARP -A 看到它,它会给出最近看到的机器的 IP 地址。通常每台机器每 15 分钟 ARP 一次,如果 1/2 小时后没有看到,则从 ARP 表中删除。
-
一种理论可能是控制器最近下线但仍在 ARP 表中。
-
@jdweng 1) 据我了解.net 路由,一旦构建了端点表,就根本无法删除端点。 2)如果没有现有端点对给定的路由值无效,则后备端点像最后的端点一样工作,在我的情况下,后备配置在第二个代码块的末尾使用以下行:
endpoints.MapFallbackToController("Index", "Fallback");,因此它将扫描所有现有端点,并且如果没有合适的,它应该转到后备控制器的索引操作。但此操作并未以某种方式注册为端点
标签: c# asp.net .net-core asp.net-core-3.1