From 57c12fa81acbb58a5182e974974e621df1bc0ed0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?jian=E7=8E=84=E5=86=B0?= Date: Tue, 25 Oct 2022 11:28:47 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=85=BC=E5=AE=B9=20Http=20=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=202=E7=A7=8D=20=E5=8F=82=E6=95=B0=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E6=9E=9A=E4=B8=BE=E7=9A=84=E6=8F=8F=E8=BF=B0?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/DemoController.cs | 61 ++++++---- .../Models/GroupSample.cs | 26 ++++ .../Models/QuerySample.cs | 68 +++++++++++ .../Models/Requests/EnumDictionaryRequest.cs | 6 + .../Requests/PostJsonPropertyRequest.cs | 56 +++++++++ .../Responses/EnumDictionaryResponse.cs | 112 ++++++++++++++++++ .../Bing.Samples.ApiGroup_v3/Models/Result.cs | 51 ++++++++ .../Models/UploadSample.cs | 30 +++++ .../Bing.Extensions.Swashbuckle.xml | 27 +++++ .../Bing/Swashbuckle/EnumHandleBase.cs | 22 ++++ .../Extensions/SwaggerGenExtensions.cs | 4 +- .../EnumDescriptionsParameterFilter.cs | 24 +++- .../Schemas/EnumDescriptionSchemaFilter.cs | 6 +- .../Bing/Swashbuckle/SwaggerExOptions.cs | 13 ++ 14 files changed, 473 insertions(+), 33 deletions(-) create mode 100644 samples/Bing.Samples.ApiGroup_v3/Models/GroupSample.cs create mode 100644 samples/Bing.Samples.ApiGroup_v3/Models/QuerySample.cs create mode 100644 samples/Bing.Samples.ApiGroup_v3/Models/Requests/EnumDictionaryRequest.cs create mode 100644 samples/Bing.Samples.ApiGroup_v3/Models/Requests/PostJsonPropertyRequest.cs create mode 100644 samples/Bing.Samples.ApiGroup_v3/Models/Responses/EnumDictionaryResponse.cs create mode 100644 samples/Bing.Samples.ApiGroup_v3/Models/Result.cs create mode 100644 samples/Bing.Samples.ApiGroup_v3/Models/UploadSample.cs diff --git a/samples/Bing.Samples.ApiGroup_v3/Controllers/DemoController.cs b/samples/Bing.Samples.ApiGroup_v3/Controllers/DemoController.cs index 3b3016c..7822711 100644 --- a/samples/Bing.Samples.ApiGroup_v3/Controllers/DemoController.cs +++ b/samples/Bing.Samples.ApiGroup_v3/Controllers/DemoController.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using Bing.Samples.ApiGroup.Models; +using Bing.Samples.ApiGroup.Models.Responses; using Bing.Samples.Common; using Bing.Swashbuckle.Attributes; using Microsoft.AspNetCore.Mvc; @@ -10,54 +11,62 @@ namespace Bing.Samples.ApiGroup.Controllers /// [ApiController] [SwaggerApiGroup(ApiGroupSample.Demo)] - [Route("api/[controller]")] + [Route("api/[controller]/[action]")] public class DemoController:Controller { /// - /// 获取列表 + /// 上传文件 /// - [HttpGet] - public ActionResult> Get() + /// 上传信息 + [HttpPost] + public Result Upload([FromForm] UploadSample sample) { - return new string[] { "value1", "value2" }; + return Result.Success(sample.Name); } /// - /// 获取详情 + /// 查询 /// - /// 标识 - [HttpGet("{id}")] - public ActionResult Get(int id) + /// 查询 + [HttpGet] + public virtual Result Query([FromQuery] QuerySample sample) { - return "value"; + return Result.Success(sample); } /// - /// 新增 + /// 获取默认值 /// - /// 值 - [HttpPost] - public void Post([FromBody] string value) + /// 字符串 + /// 页索引 + /// 每页记录数 + /// 枚举例子 + [HttpGet] + public virtual Result GetDefaultValue([FromQuery] string q, [FromQuery] int page = 1, [FromQuery] int pageSize = 20, [FromQuery] EnumSample enumSample = EnumSample.Two) { + return Result.Success(new + { + q, + page, + pageSize + }); } /// - /// 修改 + /// 提交 /// - /// 标识 - /// 值 - [HttpPut("{id}")] - public void Put(int id, [FromBody] string value) + /// 查询例子 + [HttpPost] + public Result Post([FromBody] QuerySample sample) { + return Result.Success(sample); } /// - /// 删除 + /// 测试 枚举字典响应 /// - /// 标识 - [HttpDelete("{id}")] - public void Delete(int id) - { - } + [HttpGet("TestEnumDictionaryResp")] + [ProducesResponseType(typeof(EnumDictionaryResponse), 200)] + public IActionResult TestEnumDictionaryResp() => new JsonResult(new EnumDictionaryResponse()); } } diff --git a/samples/Bing.Samples.ApiGroup_v3/Models/GroupSample.cs b/samples/Bing.Samples.ApiGroup_v3/Models/GroupSample.cs new file mode 100644 index 0000000..f29bcb3 --- /dev/null +++ b/samples/Bing.Samples.ApiGroup_v3/Models/GroupSample.cs @@ -0,0 +1,26 @@ +using Bing.Swashbuckle.Attributes; + +namespace Bing.Samples.ApiGroup.Models +{ + /// + /// 分组例子 + /// + public enum GroupSample + { + /// + /// 登录 + /// + [SwaggerApiGroupInfo(Title = "登录模块", Description = "登录模块相关接口")] + Login, + /// + /// 测试 + /// + [SwaggerApiGroupInfo(Title = "测试模块", Description = "测试相关接口")] + Test, + /// + /// 案例 + /// + [SwaggerApiGroupInfo(Title = "Demo模块", Description = "案例模块相关接口")] + Demo + } +} diff --git a/samples/Bing.Samples.ApiGroup_v3/Models/QuerySample.cs b/samples/Bing.Samples.ApiGroup_v3/Models/QuerySample.cs new file mode 100644 index 0000000..d0f566e --- /dev/null +++ b/samples/Bing.Samples.ApiGroup_v3/Models/QuerySample.cs @@ -0,0 +1,68 @@ +using System; +using System.ComponentModel; +using Bing.Swashbuckle.Attributes; + +namespace Bing.Samples.ApiGroup.Models +{ + /// + /// 查询例子 + /// + public class QuerySample + { + /// + /// 编号 + /// + public Guid Id { get; set; } + + /// + /// 名称 + /// + [DefaultValue("隔壁老黑")] + public string Name { get; set; } = "隔壁老王"; + + /// + /// 密码 + /// + [SwaggerIgnoreProperty] + public string Password { get; set; } + + /// + /// 性别 + /// + [DefaultValue(1)] + public int Gender { get; set; } = 2; + + /// + /// 创建时间 + /// + public DateTime CreateTime { get; set; } + + /// + /// 枚举例子 + /// + [DefaultValue(EnumSample.Two)] + public EnumSample EnumSample { get; set; } + } + + /// + /// 枚举例子 + /// + public enum EnumSample + { + /// + /// 老大 + /// + [Description("老大")] + One = 1, + /// + /// 老二 + /// + [Description("老二")] + Two = 2, + /// + /// 老三 + /// + [Description("老三")] + Three = 3 + } +} diff --git a/samples/Bing.Samples.ApiGroup_v3/Models/Requests/EnumDictionaryRequest.cs b/samples/Bing.Samples.ApiGroup_v3/Models/Requests/EnumDictionaryRequest.cs new file mode 100644 index 0000000..0dc7a7d --- /dev/null +++ b/samples/Bing.Samples.ApiGroup_v3/Models/Requests/EnumDictionaryRequest.cs @@ -0,0 +1,6 @@ +namespace Bing.Samples.ApiGroup.Models.Requests +{ + public class EnumDictionaryRequest + { + } +} diff --git a/samples/Bing.Samples.ApiGroup_v3/Models/Requests/PostJsonPropertyRequest.cs b/samples/Bing.Samples.ApiGroup_v3/Models/Requests/PostJsonPropertyRequest.cs new file mode 100644 index 0000000..b154e43 --- /dev/null +++ b/samples/Bing.Samples.ApiGroup_v3/Models/Requests/PostJsonPropertyRequest.cs @@ -0,0 +1,56 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace Bing.Samples.ApiGroup.Models.Requests +{ + /// + /// Post Json属性请求 + /// + public class PostJsonPropertyRequest + { + /// + /// 名称 + /// + public string Name { get; set; } + + /// + /// 昵称 + /// + [JsonProperty("nickname")] + public string OtherName { get; set; } + + /// + /// Json属性名 + /// + [JsonPropertyName("jsonPropertyName")] + public string SerializeName { get; set; } + + /// + /// 子属性 + /// + public PostJsonPropertyChildRequest Child { get; set; } + } + + /// + /// Post Json子属性请求 + /// + public class PostJsonPropertyChildRequest + { + /// + /// 名称 + /// + public string Name { get; set; } + + /// + /// 昵称 + /// + [JsonProperty("nickname")] + public string OtherName { get; set; } + + /// + /// Json属性名 + /// + [JsonPropertyName("jsonPropertyName")] + public string SerializeName { get; set; } + } +} diff --git a/samples/Bing.Samples.ApiGroup_v3/Models/Responses/EnumDictionaryResponse.cs b/samples/Bing.Samples.ApiGroup_v3/Models/Responses/EnumDictionaryResponse.cs new file mode 100644 index 0000000..58a2364 --- /dev/null +++ b/samples/Bing.Samples.ApiGroup_v3/Models/Responses/EnumDictionaryResponse.cs @@ -0,0 +1,112 @@ +using System.Collections.Generic; +using System.ComponentModel; + +namespace Bing.Samples.ApiGroup.Models.Responses +{ + /// + /// 枚举字典响应 + /// + public class EnumDictionaryResponse + { + /// + /// 单据状态 + /// + public Dictionary StatusDic { get; set; } + + /// + /// 异常状态 + /// + public Dictionary ErrorCodeDic { get; set; } + } + + /// + /// 发货状态枚举 + /// + public enum SendNoticeOrderStatus + { + /// + /// 待组合 + /// + [Description("待组合")] + WaitForCombination = 0, + + /// + /// 待拣货 + /// + [Description("待拣货")] + WaitForPicking = 1, + + /// + /// 拣货中 + /// + [Description("拣货中")] + Picking = 2, + + /// + /// 待打包 + /// + [Description("待打包")] + WaitForPacking = 3, + + /// + /// 待发货 + /// + [Description("待发货")] + Packed = 4, + + /// + /// 部分发货 + /// + [Description("部分发货")] + PartialSent = 6, + + /// + /// 全部发货 + /// + [Description("全部发货")] + Sent = 7, + + /// + /// 已取消 + /// + [Description("已取消")] + Cancel = 8, + + /// + /// 通知电商中 + /// + [Description("通知电商中")] + NoticingEShop = 9, + + /// + /// 通知TMS中 + /// + [Description("通知TMS中")] + NoticingTms = 10 + + } + + /// + /// 发货单异常枚举 + /// + public enum SendOrderErrorCode + { + /// + /// 正常 + /// + [Description("正常")] + Normal = 0, + + /// + /// 系统缺货 + /// + [Description("系统缺货")] + SysQtyShort = 1, + + /// + /// 实物缺货 + /// + [Description("实物缺货")] + RealQtyShort = 2, + } +} diff --git a/samples/Bing.Samples.ApiGroup_v3/Models/Result.cs b/samples/Bing.Samples.ApiGroup_v3/Models/Result.cs new file mode 100644 index 0000000..94066f8 --- /dev/null +++ b/samples/Bing.Samples.ApiGroup_v3/Models/Result.cs @@ -0,0 +1,51 @@ +namespace Bing.Samples.ApiGroup.Models +{ + /// + /// 结果 + /// + public class Result + { + /// + /// 编码 + /// + public int Code { get; set; } + + /// + /// 消息 + /// + public string Message { get; set; } + + /// + /// 返回消息 + /// + public object Data { get; set; } + + /// + /// 请求成功 + /// + /// + /// + public static Result Success(object data = null) + { + var result = new Result(); + result.Code = 0; + result.Message = "请求成功"; + result.Data = data; + return result; + } + + /// + /// 请求失败 + /// + /// + /// + /// + public static Result Fail(int code=1, string message="请求失败") + { + var result = new Result(); + result.Code = code; + result.Message = message; + return result; + } + } +} diff --git a/samples/Bing.Samples.ApiGroup_v3/Models/UploadSample.cs b/samples/Bing.Samples.ApiGroup_v3/Models/UploadSample.cs new file mode 100644 index 0000000..1b68afa --- /dev/null +++ b/samples/Bing.Samples.ApiGroup_v3/Models/UploadSample.cs @@ -0,0 +1,30 @@ +using Microsoft.AspNetCore.Http; + +namespace Bing.Samples.ApiGroup.Models +{ + /// + /// 上传文件 + /// + public class UploadSample + { + /// + /// 文件 + /// + public IFormFile File { get; set; } + + /// + /// 第二个文件 + /// + public IFormFile TwoFile { get; set; } + + /// + /// 名称 + /// + public string Name { get; set; } = "666"; + + /// + /// 尺寸大小 + /// + public int Size { get; set; } + } +} diff --git a/src/Bing.Extensions.Swashbuckle/Bing.Extensions.Swashbuckle.xml b/src/Bing.Extensions.Swashbuckle/Bing.Extensions.Swashbuckle.xml index 6900fa7..471a446 100644 --- a/src/Bing.Extensions.Swashbuckle/Bing.Extensions.Swashbuckle.xml +++ b/src/Bing.Extensions.Swashbuckle/Bing.Extensions.Swashbuckle.xml @@ -541,6 +541,13 @@ 枚举类型 + + + 格式化描述 + + 描述 + 枚举类型 + 服务扩展 @@ -1188,6 +1195,13 @@ 重写操作处理 + + + 设置API参数描述信息 + + API参数 + 类型 + 枚举描述 过滤器。支持Body参数内容 @@ -1609,6 +1623,19 @@ Api分组类型 + + + 枚举前缀 + + + + + 枚举项格式化 + + + 0 : 值, 1 : 名称, 2 : 描述 + + Swagger授权登录账号,未指定则不启用 diff --git a/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/EnumHandleBase.cs b/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/EnumHandleBase.cs index 26cb8f8..4431211 100644 --- a/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/EnumHandleBase.cs +++ b/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/EnumHandleBase.cs @@ -1,5 +1,6 @@ using System; using System.Text; +using Bing.Swashbuckle.Internals; using Enum = Bing.Swashbuckle.Internals.Enum; namespace Bing.Swashbuckle @@ -21,5 +22,26 @@ protected virtual string FormatDescription(Type type) sb.Append($"{item.Value} = {(string.IsNullOrEmpty(item.Description) ? item.Name : item.Description)}{Environment.NewLine}"); return sb.ToString(); } + + /// + /// 格式化描述 + /// + /// 描述 + /// 枚举类型 + protected virtual string FormatDescription(string description, Type type) + { + var sb = new StringBuilder(description); + var enumPrefix = BuildContext.Instance.ExOptions.EnumPrefix; + if (!string.IsNullOrEmpty(enumPrefix)) + sb.Append(enumPrefix); + sb.AppendLine("
    "); + foreach (var item in Enum.GetDescriptions(type)) + { + var itemDesc = string.Format(BuildContext.Instance.ExOptions.EnumItemFormat, item.Value, item.Name, item.Description); + sb.AppendLine($"
  • {itemDesc}
  • "); + } + sb.AppendLine("
"); + return sb.ToString(); + } } } diff --git a/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/Extensions/SwaggerGenExtensions.cs b/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/Extensions/SwaggerGenExtensions.cs index 052552f..a3d827c 100644 --- a/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/Extensions/SwaggerGenExtensions.cs +++ b/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/Extensions/SwaggerGenExtensions.cs @@ -24,10 +24,10 @@ public static class SwaggerGenExtensions /// Swagger生成选项 public static void ShowEnumDescription(this SwaggerGenOptions options) { - if (!options.ParameterFilterDescriptors.Exists(x => x.Type == typeof(EnumDescriptionsParameterFilter))) - options.ParameterFilter(); if (!options.SchemaFilterDescriptors.Exists(x => x.Type == typeof(EnumDescriptionSchemaFilter))) options.SchemaFilter(); + if (!options.ParameterFilterDescriptors.Exists(x => x.Type == typeof(EnumDescriptionsParameterFilter))) + options.ParameterFilter(); } #endregion diff --git a/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/Filters/Parameters/EnumDescriptionsParameterFilter.cs b/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/Filters/Parameters/EnumDescriptionsParameterFilter.cs index 2207f18..702758d 100644 --- a/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/Filters/Parameters/EnumDescriptionsParameterFilter.cs +++ b/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/Filters/Parameters/EnumDescriptionsParameterFilter.cs @@ -14,11 +14,29 @@ internal class EnumDescriptionsParameterFilter : EnumHandleBase, IParameterFilte ///
public void Apply(OpenApiParameter parameter, ParameterFilterContext context) { - var type = context.ParameterInfo?.ParameterType; + if (context.PropertyInfo != null) + { + var type = context.PropertyInfo?.PropertyType; + SetDescription(parameter,type); + } + else + { + var type = context.ParameterInfo?.ParameterType; + SetDescription(parameter, type); + } + } + + /// + /// 设置API参数描述信息 + /// + /// API参数 + /// 类型 + private void SetDescription(OpenApiParameter parameter, Type type) + { if (type == null) return; - if (type.IsEnum) - parameter.Description = $"{parameter.Description}{Environment.NewLine}{FormatDescription(type)}"; + if (type.IsEnum) + parameter.Description = FormatDescription(parameter.Description, type); } } } diff --git a/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/Filters/Schemas/EnumDescriptionSchemaFilter.cs b/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/Filters/Schemas/EnumDescriptionSchemaFilter.cs index 90247a4..288114c 100644 --- a/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/Filters/Schemas/EnumDescriptionSchemaFilter.cs +++ b/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/Filters/Schemas/EnumDescriptionSchemaFilter.cs @@ -14,8 +14,10 @@ internal class EnumDescriptionSchemaFilter : EnumHandleBase, ISchemaFilter /// public void Apply(OpenApiSchema schema, SchemaFilterContext context) { - if (context.Type.IsEnum) - schema.Description = $"{schema.Description}{Environment.NewLine}{FormatDescription(context.Type)}"; + var type = context.Type; + if(!type.IsEnum) + return; + schema.Description = FormatDescription(schema.Description, type); } } } diff --git a/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/SwaggerExOptions.cs b/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/SwaggerExOptions.cs index acd5ed5..5d06a01 100644 --- a/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/SwaggerExOptions.cs +++ b/src/Bing.Extensions.Swashbuckle/Bing/Swashbuckle/SwaggerExOptions.cs @@ -54,6 +54,19 @@ public SwaggerExOptions() { } /// public Type ApiGroupType { get; set; } + /// + /// 枚举前缀 + /// + public string EnumPrefix { get; set; } = "

枚举值:

"; + + /// + /// 枚举项格式化 + /// + /// + /// 0 : 值, 1 : 名称, 2 : 描述 + /// + public string EnumItemFormat { get; set; } = "{0} - {1}: {2}"; + /// /// Swagger授权登录账号,未指定则不启用 ///