簡體   English   中英

我可以使用 Ocelot 將 POST http 請求重新路由到 GET http 請求嗎?

[英]Can I Reroute POST http request to a GET http request with Ocelot?

我們有一個 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 中配置它以便正確重新路由? 如果是這樣,你能指出我正確的方向嗎?

我認為這就是你需要的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 添加到 ocelot.json 中的特定 ReRoute。 數組中的名稱必須與 Ocelot 的 DelegatingHandlers 的類名稱匹配才能將它們匹配在一起。

"DelegatingHandlers": [
    "PostToGetHandler"
]

我建議最初向您的 Ocelot 實例添加一個簡單的處理程序並進行測試並添加到它以使其執行您想要的操作。 我希望這有助於你想做的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM