.net中swagger的使用

261 阅读2分钟

引入swagger的步骤

WebApi项目自带swagger,如果要自己引入,参考下面的步骤

www.cnblogs.com/green-jcx/p…

//Nuget

Swashbuckle.AspNetCore

1、注册Swagger服务

builder.Services.AddSwaggerGen(c => {
    c.SwaggerDoc("v1", new() { Title = "项目管理接口", Version = "v1", Description = "项目管理接口说明文档", });
});

2、启用中间件

配置两个中间件分别是:UseSwagger和UseSwaggerUI

app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "ProjectService.WebAPI v1"));

让Swagger中调试带JWT的请求

下面的配置,可以在swagger中请求携带token(未测试,杨中科的项目模板配置过)

方法一:原生方法

//这是原生方法
builder.Services.AddSwaggerGen(c => {
    var scheme = new OpenApiSecurityScheme() {
        Description = "Authorization header. \r\nExample: 'Bearer 12345abcdef'",
        Reference = new OpenApiReference {
            Type = ReferenceType.SecurityScheme,
            Id = "Authorization"
        },
        Scheme = "oauth2",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.ApiKey,
    };
    c.AddSecurityDefinition("Authorization", scheme);
    var requirement = new OpenApiSecurityRequirement();
    requirement[scheme] = new List<string>();
    c.AddSecurityRequirement(requirement);
};

方法二:封装,采用扩展方法

public static class SwaggerGenOptionsExtensions {
    public static void AddAuthenticationHeader(this SwaggerGenOptions c) {
        c.AddSecurityDefinition("Authorization", new OpenApiSecurityScheme {
            Description = "Authorization header. \r\nExample: 'Bearer 12345abcdef'",
            Name = "Authorization",
            In = ParameterLocation.Header,
            Type = SecuritySchemeType.ApiKey,
            Scheme = "Authorization"
        });
        c.AddSecurityRequirement(new OpenApiSecurityRequirement
        {
            {
                new OpenApiSecurityScheme
                {
                    Reference = new OpenApiReference
                    {
                        Type = ReferenceType.SecurityScheme,
                        Id = "Authorization"
                    },
                    Scheme = "oauth2",
                    Name = "Authorization",
                    In = ParameterLocation.Header
                },
                new List<string>()
            }
        });
    }
}

注册swagger服务,使用扩展方法

//启用Swagger中的【Authorize】按钮。这样就不用每个项目的AddSwaggerGen中单独配置了
builder.Services.Configure<SwaggerGenOptions>(c => {
    c.AddAuthenticationHeader();
});

接口文档配置为项目首页

目的是将Swagger接口文档设置为我们项目的首页(启动页),不必在浏览器中单独输入“/swagger”的标识。

网上的方法,未测试

1、将“launchSetting.json”文件中的“launchUrl”属性删除

{
  "$schema": "https://json.schemastore.org/launchsettings.json",
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:16933",
      "sslPort": 44324
    }
  },
  "profiles": {
    "ProjectService.WebAPI": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "launchUrl": "swagger",//删除这里
      "applicationUrl": "https://localhost:7073;http://localhost:5073",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "swagger",//删除这里
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

2、启用swagger,UseSwaggerUI时,对其加入一个RoutePrefix属性,将其赋值为空字符

app.UseSwaggerUI(c => {
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "ProjectService.WebAPI v1");
    //添加下面的这行
    c.RoutePrefix = "";
});

文档注释

给接口方法添加注释

步骤很简单

1、在Controller中的控制器类或方法添加注释信息

/// <summary>
/// 获取数据
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
[HttpPost]
public async Task<ActionResult<ApiResult>> Get(EquipRequest req) {
    //...
}

2、对webapi项目进行配置,输出xml文件

Swagger中接口对应的注释信息是通过一个XML文件进行维护的,因此我们需要对项目配置一个用于存储Swagger接口注释信息的XML文件,方法如下

1)右键webapi项目,打开“属性”页

2)属性--生成--输出--勾选“文档文件”,

3)勾选后会弹出文本框让你选择一个XML文件的生成路径,如果使用默认位置,可不填写路径。如果要自定义填写,推荐填写相对路径。

生成的文档目录:

C:\Users\p30001084b002\source\repos\维护履历管理系统\ProjectService.WebAPI\obj\Debug\net6.0\ProjectService.WebAPI.xml

注意:

  • 这里自己的电脑上自己选择位置会崩溃,可能vs没装好
  • 生成的文档名是ProjectService.WebAPI.xml,这个暂时没有找到自己重命名的方法
  • 生成的文档不会直接在vs中显示出来

3、修改注册Swagger服务的配置,添加对此xml文件的引用

builder.Services.AddSwaggerGen(c => {
    c.SwaggerDoc("v1", new() { Title = "项目管理接口", Version = "v1", Description = "项目管理接口说明文档", });
    //下面是增加对XML文件的引用代码
    var basePath = AppContext.BaseDirectory;    //"..\obj\Debug\net6.0"
    var xmlPath = Path.Combine(basePath, "ProjectService.WebAPI.xml");
    c.IncludeXmlComments(xmlPath, true);
});

给接口有关实体类添加注释

1、在领域层的实体类中添加注释信息

2、对领域层项目进行配置,输出xml文件(方法同上)

默认的xml文件名是“ProjectService.Domain.xml”

3、修改注册Swagger服务的配置,添加对此xml文件的引用

builder.Services.AddSwaggerGen(c => {
    c.SwaggerDoc("v1", new() { Title = "项目管理接口", Version = "v1", Description = "项目管理接口说明文档", });
    var basePath = AppContext.BaseDirectory;
    var controllerXmlPath = Path.Combine(basePath, "ProjectService.WebAPI.xml");
    var modelXmlPath = Path.Combine(basePath, "ProjectService.Domain.xml");//领域层实体的xml路径
    c.IncludeXmlComments(controllerXmlPath, true);
    c.IncludeXmlComments(modelXmlPath, true);//使用领域层实体的xml文件注释
});

取消未填写注释的警告信息

无关紧要,暂未测试

我们在为Swagger中的接口或Model添加注释信息后,会有一个现象:那就是项目下的所有类型或成员,都出现警告提示要求添加注释信息。如果不想添加注释,又不想看到这个警告提示,可以这样做:

项目右键,选择属性--生成--错误和警告--取消显示警告--添加1591的代码

//注:1701;1702是本来就有的代码

1701;1702;1591

给测试数据加默认值

/// 2023-02-12

Swagger不显示某些方法

添加一个Attribute即可,添加后对应的方法或接口就不会出现在Swagger文档中了。

[ApiExplorerSettings(IgnoreApi =true)]    //这个就是要添加的Attribute
[HttpPost]
public async Task<ActionResult<ApiResult>> Get(EquipRequest req) {
//...
}

方法画删除线

添加一个[Obsolete]即可

解决swagger中文注释乱码问题

1、安装扩展

2、将高级保存选项设置到菜单栏

工具-自定义

命令--文件

添加命令-文件-高级保存选项

3、点击“高级保存选项”,会弹出保存格式,应该是utf-8才不会乱码

为Swagger增加Authentication报文头

给SwaggerGenOptions对象增加了一个扩展方法AddAuthenticationHeader,使用时只需要

builder.Services.Configure<SwaggerGenOptions>(c => {
    c.AddAuthenticationHeader();
});

源码

public static void AddAuthenticationHeader(this SwaggerGenOptions c) {
    c.AddSecurityDefinition("Authorization", new OpenApiSecurityScheme {
        Description = "Authorization header. \r\nExample: 'Bearer 12345abcdef'",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.ApiKey,
        Scheme = "Authorization"
    });
	c.AddSecurityRequirement(new OpenApiSecurityRequirement()
                         {
                             {
                                 new OpenApiSecurityScheme
                                 {
                                     Reference = new OpenApiReference
                                     {
                                         Type = ReferenceType.SecurityScheme,
                                         Id = "Authorization"
                                     },
                                     Scheme = "oauth2",
                                     Name = "Authorization",
                                     In = ParameterLocation.Header,
                                 },
                                 new List<string>()
                             }
                         });
}

Swagger支持和版本控制

可以控制哪些方法存在于哪个版本的在线文档中

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
                               {
                                   options.SwaggerDoc("v1", new() { Title = "朝夕教育 MinimalApi-v1版本", Version 
        = "v1" });
                                   options.SwaggerDoc("v2", new() { Title = "朝夕教育 MinimalApi-v2版本", Version 
        = "v2" });
                               });
app.MapPost("api/ParaModel", ([FromBody] Commodity commodity) => Newtonsoft.Json.JsonConvert.SerializeObject(commodity)).WithGroupName("v1");
app.MapPost("api/ParaList", ([FromForm] List<Commodity> commodities) => Newtonsoft.Json.JsonConvert.SerializeObject(commodities)).WithGroupName("v2");

app.UseSwagger();
app.UseSwaggerUI(options =>
                 {
                     options.EnableTryItOutByDefault();
                     options.SwaggerEndpoint("/swagger/v1/swagger.json", $" 朝夕教育 MinimalApi-v1版本 v1");
                     options.SwaggerEndpoint("/swagger/v2/swagger.json", $" 朝夕教育 MinimalApi-v2版本 v2");
                 });

扩展支持Swagger选择文件

    app.MapPost("api/UploadFile", (HttpRequest request) => {
        var form = request.ReadFormAsync().Result;
        return new JsonResult(new {
            Success = true,
            Message = "上传成功",
            FileName = form.Files.FirstOrDefault()?.FileName
        });

    }).Accepts<HttpRequest>("multipart/form-data");

上传地址

<div class="form-group">
  <input id="file-4" type="file" class="file" data-upload-url="http://localhost:5059/api/UploadFile">
</div>

步骤

1、创建类,实现IOperationFilter接口

public class SwaggerFileUploadFilter : IOperationFilter
    {
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
        	//上传内容为表单提交
            const string FileUploadContentType = "multipart/form-data";
        	//body为null或者不包含表单提交,直接返回
            if (operation.RequestBody == null ||
                !operation.RequestBody.Content.Any(x =>
                x.Key.Equals(FileUploadContentType, StringComparison.InvariantCultureIgnoreCase)))
            {
                return;
            }

            if (context.ApiDescription.ParameterDescriptions[0].Type == typeof(HttpRequest))
            {
                operation.RequestBody = new OpenApiRequestBody
                {
                	//描述信息
                    Description = "文件上传",
                    Content = new Dictionary<String, OpenApiMediaType>
                {
                    {
                        FileUploadContentType, new OpenApiMediaType
                        {
                            Schema = new OpenApiSchema
                            {
                                Type = "object",
                            	//需要文件
                                Required = new HashSet<String>{ "file" },
                                Properties = new Dictionary<String, OpenApiSchema>
                                {
                                    {
                                        "file", new OpenApiSchema()
                                        {
                                            Type = "string",
                                        	//上传二进制流
                                            Format = "binary"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                };
            }
        }
    }

2、添加此功能

builder.Services.AddSwaggerGen(options =>
                               {
                                   //...
                                   options.OperationFilter<SwaggerFileUploadFilter>();
                               });