简体   繁体   English

Ocelot - 更改网关中的上游请求正文不会导致下游请求发生变化

[英]Ocelot - Changing the upstream request body in gateway causes no change on downstream request

I'm designing microservice architecture as below:我正在设计微服务架构如下:

微服务架构

Gateway uses Ocelot to forward requests. Gateway 使用 Ocelot 转发请求。 I would like to change the body in request received from mobile device on gateway side and add inside the body new GUID.我想更改从网关端的移动设备收到的请求中的正文,并在正文中添加新的 GUID。 Microservices uses CQRS pattern, so command shouldn't returns anything.微服务使用 CQRS 模式,因此命令不应返回任何内容。 I implemented custom middleware to change DownstreamContext:我实现了自定义中间件来更改 DownstreamContext:

    public override async Task Execute(DownstreamContext context)
    {
        var secondRequest = JObject.Parse(await context.DownstreamRequest.Content.ReadAsStringAsync());

        secondRequest["token"] = "test";
        secondRequest["newId"] = Guid.NewGuid();

        context.DownstreamRequest.Content = new StringContent(secondRequest.ToString(), Encoding.UTF8);

        await this.Next(context);
    }

I debugged this and content of DownstreamRequest before call await this.Next(context);在调用 await this.Next(context); 之前,我调试了这个和 DownstreamRequest 的内容; is changed, but request incoming to microservice is not changed.已更改,但传入微服务的请求未更改。 Is there any way to change request in gateway and forward this request to microservice in a changed form?有什么方法可以更改网关中的请求并将此请求以更改的形式转发到微服务?

You can use for it a custom middleware您可以使用自定义中间件

public class SetGuidMiddleware
{
    private readonly RequestDelegate _next

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

    public async Task Invoke(HttpContext context)
    {
        if (!HttpMethods.IsGet(context.Request.Method)
           && !HttpMethods.IsHead(context.Request.Method)
           && !HttpMethods.IsDelete(context.Request.Method)
           && !HttpMethods.IsTrace(context.Request.Method)
           && context.Request.ContentLength > 0)
        {
            //This line allows us to set the reader for the request back at the beginning of its stream.
            context.Request.EnableRewind();

            var buffer = new byte[Convert.ToInt32(context.Request.ContentLength)];
            await context.Request.Body.ReadAsync(buffer, 0, buffer.Length);
            var bodyAsText = Encoding.UTF8.GetString(buffer);

            var secondRequest = JObject.Parse(bodyAsText);
            secondRequest["token"] = "test";
            secondRequest["newId"] = Guid.NewGuid();

            var requestContent = new StringContent(secondRequest.ToString(), Encoding.UTF8, "application/json");
            context.Request.Body = await requestContent.ReadAsStreamAsync();
        }

        await _next(context);
    }
}

and use it before Ocelot并在 Ocelot 之前使用它

app.UseMiddleware<SetGuidMiddleware>();
app.UseOcelot().Wait();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM