c# - 我可以使用 Ocelot 将 POST http 请求重新路由到 GET http 请求吗?
问题描述
我们有一个 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。数组中的名称必须与您的 DelegatingHandlers 的类名称匹配,以便 Ocelot 将它们匹配在一起。
"DelegatingHandlers": [
"PostToGetHandler"
]
我建议最初向您的 Ocelot 实例添加一个简单的处理程序,然后对其进行测试并添加以使其执行您想要的操作。我希望这对您想做的事情有所帮助。
推荐阅读
- c# - Unity Firebase 存储读取图像不起作用
- python - API 端点返回 TypeError: 'type' object is not iterable
- swift - 由于没有 EnvironmentObject 的弹出框导致 SwiftUI Mac OS 崩溃
- android - Gradle 同步失败:没有缓存版本的 com.android.tools.build:gradle:6.2.2 可用于离线模式
- php - 为什么我从 html 生成的 pdf 文档看起来很奇怪?
- python-3.x - 如何正确编写用于执行和绘制 for 循环操作的语法?
- node.js - 在使用 Zeit Now 部署的快速应用程序中,有没有办法查看服务器端控制台日志?
- angularjs - AngularJs - 使用“控制器作为”语法的 ag-grid rowData
- c++ - C++ Set 的迭代器默认为 const 防止插入
- javascript - 反应原生:有办法安排平面列表吗?