简体   繁体   中英

Ocelot API Gateway Custom Aggregator Issue in ASP.NET Core 3.1

I'm implementing custom Aggregator using Ocelot in ASP.NET it's throwing error in Startup.cs Ocelot middleware. However, both Microservices are working fine and fetching the data independently.

When I'm calling them from my API Gateway it's throwing below error.

在此处输入图像描述

Startup.cs

public class Startup

{
    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddOcelot()
            .AddSingletonDefinedAggregator<MyAggregator>();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public async void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
        await app.UseOcelot();
    }
}

Here is my ocelot.json file for routes of different Microservices.

ocelot.json


{
  "ReRoutes": [
    {
      "DownstreamPathTemplate": "/user/getUser",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": "44378"
        }
      ],
      "UpstreamPathTemplate": "/getUser",
      "Key": "User"
    },
    {
      "DownstreamPathTemplate": "/product/getProduct",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": "44357"
        }
      ],
      "UpstreamPathTemplate": "/getProduct",
      "Key": "Product"
    }
  ],
  "Aggregates": [
    {
      "ReRouteKeys": [
        "User",
        "Product"
      ],
      "UpstreamPathTemplate": "/UserAndProduct"
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "http://localhost:5000/"
  }
}

My custom aggregator class

MyAggregator.cs


public class MyAggregator : IDefinedAggregator
    {
      
        public async Task<DownstreamResponse> Aggregate(List<HttpContext> responses)
        {
            var one = await responses[0].Items.DownstreamResponse().Content.ReadAsStringAsync();
            var two = await responses[1].Items.DownstreamResponse().Content.ReadAsStringAsync();

            var contentBuilder = new StringBuilder();
            contentBuilder.Append(one);
            contentBuilder.Append(two);

            var stringContent = new StringContent(contentBuilder.ToString())
            {
                Headers = { ContentType = new MediaTypeHeaderValue("application/json") }
            };

            return new DownstreamResponse(stringContent, HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "OK");
        }
    }

You forgot to mention your custom aggregator in your ocelot.json file. Ocelot needs to know your custom aggregator whenever you hit /UserAndProduct .

"Aggregates": [ { "ReRouteKeys": [ "User", "Product" ], "UpstreamPathTemplate": "/UserAndProduct" } ]

And there is a breaking change in ocelot's latest version. Use the key Routes instead of ReRoutes . You can use the following json file.

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/user/getUser",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": "44378"
        }
      ],
      "UpstreamPathTemplate": "/getUser",
      "Key": "User"
    },
    {
      "DownstreamPathTemplate": "/product/getProduct",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": "44357"
        }
      ],
      "UpstreamPathTemplate": "/getProduct",
      "Key": "Product"
    }
  ],
  "Aggregates": [
    {
      "RouteKeys": [
        "User",
        "Product"
      ],
      "UpstreamPathTemplate": "/UserAndProduct",
      "Aggregator": "MyAggregator"
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "http://localhost:5000/"
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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