【问题标题】:Can I Reroute POST http request to a GET http request with Ocelot?我可以使用 Ocelot 将 POST http 请求重新路由到 GET http 请求吗?
【发布时间】:2019-12-07 14:01:26
【问题描述】:

我们有一个 ocelot 网关,可以将我们以前的 WCF 请求重新路由到更新的 .NET Core 服务。一些旧请求仍将发送到 WCF 服务。这一切都很好。

现在我想将带有请求模型的POST 重新路由到带有查询字符串 标头 的GET。我似乎无法弄清楚如何做到这一点,所以我有点期望查询字符串参数能够开箱即用并为标题做一些自定义。

这是我的重新路由 json:

{
      "DownstreamPathTemplate": "/v1/attachments",
      "DownstreamScheme": "http",
      "DownstreamHttpMethod": [ "GET" ],
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 53737
        }
      ],
      "UpstreamPathTemplate": "/mobile/ImageService.svc/json/GetImage",
      "UpstreamHttpMethod": [ "POST" ],
      "UpstreamHost": "*"
    }

我的请求正文:

{
    "SessionId":"XXX", //needs to be a header
    "ImageId": "D13XXX", //needs to be added to query string
    "MaxWidth" : "78", //needs to be added to query string
    "MaxHeight" : "52", //needs to be added to query string
    "EditMode": "0" //needs to be added to query string
}

是否可以在 ocelot 中配置它以便正确重新路由?如果是这样,你能指出我正确的方向吗?

【问题讨论】:

    标签: c# .net rest wcf ocelot


    【解决方案1】:

    我认为这就是你所需要的 https://ocelot.readthedocs.io/en/latest/features/delegatinghandlers.html

    我没有检查您是否更改了 http 动词等,但我猜您可以将查询字符串参数添加到后续请求(您将收到 http 请求消息)。我想你应该可以做任何你喜欢做的事!

    这是您可以实现的代码类型的未经测试示例

    public class PostToGetHandler : DelegatingHandler
    {
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            // Only want to do this if it matches our route
            // See section later on about global or route specific handlers
            if (request.RequestUri.OriginalString.Contains("/mobile/ImageService.svc/json/GetImage") && request.Method.Equals(HttpMethod.Post))
            {
                var bodyString = await request.Content.ReadAsStringAsync();
    
                // Deserialize into a MyClass that will hold your request body data
                var myClass = JsonConvert.DeserializeObject<MyClass>(bodyString);
    
                // Append your querystrings
                var builder = new QueryBuilder();
                builder.Add("ImageId", myClass.ImageId);
                builder.Add("MaxWidth", myClass.MaxWidth);      // Keep adding queryString values
    
                // Build a new uri with the querystrings
                var uriBuilder = new UriBuilder(request.RequestUri);
                uriBuilder.Query = builder.ToQueryString().Value;
    
                // TODO - Check if querystring already exists etc
                request.RequestUri = uriBuilder.Uri;
    
                // Add your header - TODO - Check to see if this header already exists
                request.Headers.Add("SessionId", myClass.SessionId.ToString());
    
                // Get rid of the POST content
                request.Content = null;
            }
    
            // On it goes either amended or not
            // Assumes Ocelot will change the verb to a GET as part of its transformation
            return await base.SendAsync(request, cancellationToken);
        }
    }
    

    在Ocelot启动中可以这样注册

    services.AddDelegatingHandler<PostToGetHandler>();
    

    services.AddDelegatingHandler<PostToGetHandler>(true);  // Make it global
    

    这些处理程序可以是全局的或特定于路由的(因此,如果您将其设为特定于路由,则可能不需要在上面的代码中进行路由检查)

    这是来自 Ocelot 文档:

    最后,如果您想要 ReRoute 特定的 DelegatingHandlers 或订购 您的特定和/或全局(稍后会详细介绍)DelegatingHandlers 那么您必须将以下json添加到特定的ReRoute中 豹猫.json。数组中的名称必须与您的类名匹配 DelegatingHandlers 让 Ocelot 将它们匹配在一起。

    "DelegatingHandlers": [
        "PostToGetHandler"
    ]
    

    我建议最初为您的 Ocelot 实例添加一个简单的处理程序,然后对其进行测试和添加以使其执行您想要的操作。我希望这对您想做的事情有所帮助。

    【讨论】:

    • 你应该将相关代码转录成答案,而不是仅仅发布一个链接。
    猜你喜欢
    • 2013-06-10
    • 2018-10-08
    • 1970-01-01
    • 2012-01-16
    • 2010-11-07
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 2018-01-04
    相关资源
    最近更新 更多