0
点赞
收藏
分享

微信扫一扫

.net8 ocelot 及 微服务下的多个swagger配置

海牙秋天 07-16 12:00 阅读 24

nuget

  • Ocelot 24.0.0
  • Ocelot.Provider.Consul 24.0.0
  • Swashbuckle.AspNetCore 6.6.2
  • Microsoft.AspNetCore.Authentication.JwtBearer 8.0.13

路由配置文件

文件名称:【configuration.json】 , 需要配置复制到输出目录
此处提供两个测试服务

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/api/Common/{url}", 
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/api/Common/{url}", 
      "UpstreamHttpMethod": [ "Get", "Post" ],
      "UseServiceDiscovery": true,
      "ServiceName": "CommonWebApi", 
      "LoadBalancerOptions": {
        "Type": "RoundRobin" 
      }
    },
    {
      "DownstreamPathTemplate": "/Common/swagger.json", 
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/Common/swagger.json", 
      "UpstreamHttpMethod": [ "Get", "Post" ],
      "UseServiceDiscovery": true,
      "ServiceName": "CommonWebApi", 
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      }
    },
    {
      "DownstreamPathTemplate": "/api/DevOps/{url}", 
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/api/DevOps/{url}", 
      "UpstreamHttpMethod": [ "Get", "Post" ],
      "UseServiceDiscovery": true,
      "ServiceName": "DevOpsWebApi", 
      "LoadBalancerOptions": {
        "Type": "RoundRobin" 
      }
    },
    {
      "DownstreamPathTemplate": "/DevOps/swagger.json", 
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/DevOps/swagger.json", 
      "UpstreamHttpMethod": [ "Get", "Post" ],
      "UseServiceDiscovery": true,
      "ServiceName": "DevOpsWebApi", 
      "LoadBalancerOptions": {
        "Type": "RoundRobin" 
      }
    }
  ],
  "GlobalConfiguration": {
    //"BaseUrl": "http://192.168.2.1:7000", 
    "ServiceDiscoveryProvider": {
      "Host": "192.168.0.1",
      "Port": 7500,
      "Type": "Consul" 
    }
  }
}

代码

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using Ocelot.Provider.Consul;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Text;

var builder = WebApplication.CreateBuilder(args);

// Add Ocelot configuration  
builder.Configuration.AddJsonFile("configuration.json", optional: false, reloadOnChange: true);

//网关项目名称
string apiName = "Gateway";

builder.Services.AddControllers();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(delegate (SwaggerGenOptions c)
{
    c.SwaggerDoc(apiName, new OpenApiInfo
    {
        Title = apiName + "接口"
    });


    //swagger文档文件名称
    var swaggerXmlName = "Gateway.xml";

    if (!string.IsNullOrWhiteSpace(swaggerXmlName.Trim()))
    {
        string[] array = swaggerXmlName.Split(',');
        foreach (string path in array)
        {
            string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path);
            if (File.Exists(filePath))
            {
                c.IncludeXmlComments(filePath, includeControllerXmlComments: true);
            }
        }
    }

    //token
    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.ApiKey
    });
    c.AddSecurityRequirement(new OpenApiSecurityRequirement {
            {
                new OpenApiSecurityScheme
                {
                    Reference = new OpenApiReference
                    {
                        Type = ReferenceType.SecurityScheme,
                        Id = "Bearer"
                    }
                },
                new List<string>()
            } });
});

builder.Services.Configure<ApiBehaviorOptions>(options =>
{
    options.InvalidModelStateResponseFactory = (context) =>
    {
        //数据验证失败时才会执行
        //返回第一条报错
        var error = context.ModelState.Values.FirstOrDefault(f => f.ValidationState != Microsoft.AspNetCore.Mvc.ModelBinding.ModelValidationState.Valid);//.Select(f => new KeyValuePair<string, IEnumerable<string>>(f.Key, f.Value.Errors.Select(e => e.ErrorMessage)));
        if (error != null && error.Errors != null && error.Errors.Count > 0)
        {
            var errMsg = error.Errors.First().ErrorMessage;
            return new JsonResult(new { Code = 1, Message = errMsg });
        }

        return new JsonResult(new { Code = 1, Message = "ModelError", Data = context.ModelState.Values });

    };
});


//JWT
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
    options.SaveToken = true;
    options.RequireHttpsMetadata = false;

    var key = "YK0cGQWeS5zuIGCov9Om7IuQAHDRV/hd2po8YtXU0cA=";

    if (string.IsNullOrWhiteSpace(key))
    {
        throw new Exception("请配置jwt key");
    }

    options.TokenValidationParameters = new TokenValidationParameters()
    {
        ValidIssuer = "BoawayCommon",
        ValidAudience = "BoawayCommon",
        ValidateIssuer = true,
        ValidateAudience = true,
        RequireExpirationTime = false,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key))
    };
});

builder.Services.AddOcelot().AddConsul();

var app = builder.Build();

string swaggerName = string.Empty;
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
    swaggerName = "Gateway";
    //app.UseSwagger();


    app.UseSwagger(c =>
    {
        c.RouteTemplate = "{documentName}/swagger.json";
    });
}
else
{
    swaggerName = "Common,DevOps";
    app.UseSwagger();
}


List<string> swaggerNameList = swaggerName.Split(",").ToList();

app.UseSwaggerUI(options =>
{
    swaggerNameList.ForEach(m =>
    {
        options.SwaggerEndpoint($"/{m}/swagger.json", m);
    });
});

//app.UseDomainServices(builder.Configuration);

app.UseRouting();

app.MapControllers();

// Use Ocelot middleware  
app.UseOcelot().Wait();
app.Run();

备注

  • 需要配置api项目输出文档
  • 需要注意configuration文件中consul的地址
  • 代码中实现了在调试模式下只显示网关中的swagger,发布模式下显示微服务下其他服务的接口文档

如果需要扩展swagger功能可以参考以下内容
[参考]
.net swagger知识点汇总 自定义swagger返回值.net5 swagger 枚举注释.net5 过滤器返回通用结构 swagger使用IApplicationModelProvider自动化添加ProducesResponseType

留待后查,同时方便他人


举报

相关推荐

0 条评论