- A+
所属分类:.NET技术
Ocelot与路由共存
引言
在Asp.Net Core中使用了Ocelot做网关之后,其自身的Api路由就不起作用了,寻了许久的解决方法,终于找到一个,主要是使用MapWhen判断Ocelot的配置是否符合,是则走转发路由,否则走自身路由,步骤如下:
1.先创建以下类
using Ocelot.Configuration.Repository; using Ocelot.DownstreamRouteFinder.Finder; using Ocelot.Middleware; namespace GateWay.Extensions { public static class OcelotExtensions { public static IApplicationBuilder UseOcelotWhenRouteMatch(this IApplicationBuilder app) => UseOcelotWhenRouteMatch(app, new OcelotPipelineConfiguration()); public static IApplicationBuilder UseOcelotWhenRouteMatch(this IApplicationBuilder app, Action<OcelotPipelineConfiguration> pipelineConfigurationAction) { var pipelineConfiguration = new OcelotPipelineConfiguration(); pipelineConfigurationAction?.Invoke(pipelineConfiguration); return UseOcelotWhenRouteMatch(app, pipelineConfiguration); } public static IApplicationBuilder UseOcelotWhenRouteMatch(this IApplicationBuilder app, OcelotPipelineConfiguration configuration) { app.MapWhen(context => { // 获取 OcelotConfiguration var internalConfigurationResponse = context.RequestServices.GetRequiredService<IInternalConfigurationRepository>().Get(); if (internalConfigurationResponse.IsError || internalConfigurationResponse.Data.Routes.Count == 0) { // 如果没有配置路由信息,不符合分支路由的条件,直接退出 return false; } var internalConfiguration = internalConfigurationResponse.Data; var downstreamRouteFinder = context.RequestServices .GetRequiredService<IDownstreamRouteProviderFactory>() .Get(internalConfiguration); // 根据请求以及上面获取的Ocelot配置获取下游路由 var response = downstreamRouteFinder.Get(context.Request.Path, context.Request.QueryString.ToString(), context.Request.Method, internalConfiguration, context.Request.Host.ToString()); // 如果有匹配路由则满足该分支路由的条件,交给 Ocelot 处理 return !response.IsError && !string.IsNullOrEmpty(response.Data?.Route?.DownstreamRoute?.FirstOrDefault() ?.DownstreamScheme); }, appBuilder => appBuilder.UseOcelot(configuration).Wait()); return app; } } }
2.在Program.cs调用
app.UseOcelotWhenRouteMatch(); // 此处调用 app.UseRouting(); app.UseHttpsRedirection(); app.UseAuthentication(); app.UseAuthorization();