You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否基于请求体中的值使用Ocelot实现路由?

可以用Ocelot根据请求体值实现路由

Ocelot支持通过自定义路由中间件或扩展路由查找逻辑,实现基于请求体中Token值的动态路由,具体实现方式如下:

1. 自定义路由中间件

编写自定义中间件解析请求体、提取Token,动态指定下游服务地址:

public class RequestBodyRoutingMiddleware
{
    private readonly RequestDelegate _next;

    public RequestBodyRoutingMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        // 开启请求体缓冲,避免后续无法重复读取
        context.Request.EnableBuffering();
        using var reader = new StreamReader(context.Request.Body, leaveOpen: true);
        var body = await reader.ReadToEndAsync();
        context.Request.Body.Position = 0;

        // 解析请求体中的Token值
        var requestData = JsonSerializer.Deserialize<dynamic>(body);
        var token = requestData?.Token?.ToString();

        // 根据Token设置下游地址
        if (token == "1")
        {
            context.Items["DownstreamTarget"] = "http://google.com";
        }
        else if (token == "2")
        {
            context.Items["DownstreamTarget"] = "http://microsoft.com";
        }

        await _next(context);
    }
}

// 扩展方法注册中间件
public static class MiddlewareExtensions
{
    public static IApplicationBuilder UseRequestBodyRouting(this IApplicationBuilder app)
    {
        return app.UseMiddleware<RequestBodyRoutingMiddleware>();
    }
}

注册中间件后,可在Ocelot的后续流程中读取context.Items中的地址,修改路由目标。

2. 扩展Ocelot路由查找逻辑

实现IRouteFinder接口,替换默认路由查找逻辑,加入请求体解析和Token判断:

public class CustomRouteFinder : IRouteFinder
{
    private readonly IRouteFinder _originalFinder;

    public CustomRouteFinder(IRouteFinder originalFinder)
    {
        _originalFinder = originalFinder;
    }

    public async Task<RouteFinderResult> Find(HttpContext httpContext)
    {
        // 先执行默认路由查找
        var result = await _originalFinder.Find(httpContext);
        if (result.IsError) return result;

        // 解析请求体Token
        httpContext.Request.EnableBuffering();
        using var reader = new StreamReader(httpContext.Request.Body, leaveOpen: true);
        var body = await reader.ReadToEndAsync();
        httpContext.Request.Body.Position = 0;

        var requestData = JsonSerializer.Deserialize<dynamic>(body);
        var token = requestData?.Token?.ToString();

        // 根据Token修改下游服务地址
        if (token == "1")
        {
            result.Route.DownstreamHostAndPorts = new List<DownstreamHostAndPort>
            {
                new DownstreamHostAndPort { Host = "google.com", Port = 80 }
            };
        }
        else if (token == "2")
        {
            result.Route.DownstreamHostAndPorts = new List<DownstreamHostAndPort>
            {
                new DownstreamHostAndPort { Host = "microsoft.com", Port = 80 }
            };
        }

        return result;
    }
}

在DI容器中替换默认实现:

services.AddOcelot()
    .AddSingleton<IRouteFinder, CustomRouteFinder>();

注意事项

  • 处理请求体时必须开启缓冲,确保后续中间件能正常读取请求内容
  • 需添加异常处理,应对非JSON格式请求体的解析失败场景
  • 中间件要注册在Ocelot路由流程之前,才能生效

内容的提问来源于stack exchange,提问作者Szymson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 10:11:17