Asp.Net Core遇到Swagger(四)-Swashbuckle技巧c篇(下)

简介: Asp.Net Core遇到Swagger(四)-Swashbuckle技巧c篇(下)

2.13 自定义架构id

如果在文档生成器遇到复杂的传入参数或响应类型,生成器会自动生成相应Json Schema,并将其添加到全局Components/Schemas字典中。

还是以天气类WeatherForecast,默认情况下,Api Json对应请求链接http://localhost:5000/v1/swaggerapi.json内容大致如下:

{
  "paths": {
    "/WeatherForecast": {
      "get": {
        "tags": [
          "GET"
        ],
        "summary": "获取天气预报信息",
        "responses": {
          "201": {
            "description": "请求成功并且服务器创建了新的资源",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    // #/components/schemas/{schemasid}
                    "$ref": "#/components/schemas/WeatherForecast"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "WeatherForecast": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "description": "日期",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "天气预报实体"
      }
    }
  }
}

修改服务中ConfigureServices的配置,自定义标识的生成规则CustomSchemaIds

public void ConfigureServices(IServiceCollection services)
{
       services.AddSwaggerGen(
          options =>
            {
                #region 自定义架构Id
                // 输出对应类型全名称
          options.CustomSchemaIds(schema => schema.FullName);
          #endregion
            }
       );
}

运行后,对应输出的Json结构如下:

{
  "paths": {
    "/WeatherForecast": {
      "get": {
        "tags": [
          "GET"
        ],
        "summary": "获取天气预报信息",
        "responses": {
          "201": {
            "description": "请求成功并且服务器创建了新的资源",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    // #/components/schemas/{schemasid}
                    "$ref": "#/components/schemas/swaggertestbase.WeatherForecast"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      // {schemasid}
      "swaggertestbase.WeatherForecast": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "description": "日期",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "天气预报实体"
      }
    }
  }
}

2.14 覆盖特定类型架构[不常用]

需要对特定类型进行指定序列化处理时,可以通过自定义架构序列化类型处理。

数据实体类:

/// <summary>
/// 天气预报实体
/// </summary>
public class WeatherForecast
{
    /// <summary>
    /// 日期
    /// </summary>
    public DateTime Date { get; set; }
    /// <summary>
    /// 温度-摄氏度
    /// </summary>
    public int TemperatureC { get; set; }
    /// <summary>
    /// 温度-华摄氏度
    /// </summary>
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
    /// <summary>
    /// 描述
    /// </summary>
    public string Summary { get; set; }
}

请求http://localhost:5000/v1/swaggerapi.json,原始Json架构如下:

"components": {
    "schemas": {
      "WeatherForecast": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "description": "日期",
            "format": "date-time"
          },
          "temperatureC": {
            "type": "integer",
            "description": "温度-摄氏度",
            "format": "int32"
          },
          "temperatureF": {
            "type": "integer",
            "description": "温度-华摄氏度",
            "format": "int32",
            "readOnly": true
          },
          "summary": {
            "type": "string",
            "description": "描述",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "天气预报实体"
      }
    }
  }

修改ConfigureServices中的AddSwaggerGen,设定类型序列化的架构为字符串。

services.AddSwaggerGen(
    options =>
    {
        #region 覆盖特定类型架构
        // 指定对应的实体类型,类型架构配置
        options.MapType<WeatherForecast>(() => new Microsoft.OpenApi.Models.OpenApiSchema { Type = "string" });
        #endregion
    }
    );

设置以后,对应的类型在架构中,无生成,目前无考虑深究原因,运行效果如下:

2.15 使用过滤器扩展生成器

1)操作过滤器

Swashbuckle会检索每一个Asp.Net Core中的每一个ApiDescription,从中提取到对应的OpenApiOperation,对应OpenApiOperation类型和ApiDescription能够通过操作过滤器列表实现传递。以包含权限认证特性,响应中401响应状态的操作过滤器为例。

创建类AuthResponsesOperationFilter实现IOperationFilter

public class AuthResponsesOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        var customAttributes = context.MethodInfo.DeclaringType.GetCustomAttributes(true)
            .Union(context.MethodInfo.GetCustomAttributes(true))
            .OfType<AuthorizeAttribute>();
        if (customAttributes.Any())
        {
            operation.Responses.Add("401", new OpenApiResponse { Description = "UnAuthorized" });
        }
    }
}

给控制器中WeatherForecastController对应Post函数添加特性Authorize

/// <summary>
/// 天气预报服务
/// </summary>
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    ........
    /// <summary>
    /// 获取Post数据
    /// </summary>
    /// <returns>处理结果</returns>
    [HttpPost]
    [Authorize]
    public string Post()
    {
        return "处理结果";
    }
    ........
}

添加到动作过滤器列表中,

services.AddSwaggerGen(
    options =>
    {
    #region 添加权限认证响应操作过滤器
    options.OperationFilter<AuthResponsesOperationFilter>();
    #endregion
    }
);

运行效果如下:

需要注意的是,过滤器管道是DI感知的。 可以使用构造函数参数创建过滤器,只要参数类型已在DI框架中注册,则它们将在过滤器实例化时自动注入。

2)架构过滤器

Swashbuckle为控制器操作公开的每个参数、响应和属性类型生成 Swagger 样式的 JSONSchema。 生成后,它通过配置的架构过滤器列表传递架构和类型。

创建枚举类型,

/// <summary>
/// 自定义枚举
/// </summary>
public enum MyEnum
{
    A,
    B,
    C
}

创建SchemaFilterController控制器,

[Route("api/[controller]")]
[ApiController]
public class SchemaFilterController : ControllerBase
{
    /// <summary>
    /// 获取SchemaFilter过滤器数据
    /// </summary>
    /// <param name="my">枚举参数</param>
    [HttpGet]
    public void Get(MyEnum my)
    { 
    }
}

自定义类AutoRestSchemaFilter,实现ISchemaFilter

/// <summary>
/// 自动设置架构过滤器
/// </summary>
public class AutoRestSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        var type = context.Type;
        if (type.IsEnum)
        {
            schema.Extensions.Add("x-ms-enum", new OpenApiObject()
            {
                ["name"] = new OpenApiString(type.Name),
                ["modelAsString"] = new OpenApiBoolean(true)
            });
        }
    }
}

添加到架构过滤器中,

....
    services.AddSwaggerGen(
                options =>
    {
        #region 添加自定义架构过滤器
    options.SchemaFilter<AutoRestSchemaFilter>();
    #endregion
    });
....

访问http://localhost:5000/v1/swaggerapi.json,可以看到对应结构如下如下,x-ms-enum在对应类型的架构尾部。

{
    "components": {
    "schemas": {
      "MyEnum": {
        "enum": [
          0,
          1,
          2
        ],
        "type": "integer",
        "description": "自定义枚举",
        "format": "int32",
        "x-ms-enum": {
          "name": "MyEnum",
          "modelAsString": true
        }
      }
    }
  }
}

通过上述例子,可以看出,对于枚举等特殊类型,实际可以通过自定义Json schema的方式实现对应字段值的备注含义。

3)文档过滤器

Document Filters在遵守OpenApi的规范前提下,可以通过文档过滤器对文档进行任意有效的Swagger Json。例如为当前文档添加额外的Tags,自定义过滤器TagDescriptionsDocumentFilter,实现IDocumentFilter

/// <summary>
/// Tag描述文档过滤器
/// </summary>
public class TagDescriptionsDocumentFilter : IDocumentFilter
{
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        swaggerDoc.Tags = new List<OpenApiTag> { 
            new OpenApiTag{ 
               Name ="Pages",
               Description = "分页类"
            },
            new OpenApiTag{
               Name ="Tests",
               Description = "测试类"
            }
        };
    }
}

添加到现有的文档过滤器中,

public void ConfigureServices(IServiceCollection services)
{
    services.AddSwaggerGen(
        options =>
        {
            //忽略部分内容
            #region 添加自定义文档过滤器
            options.DocumentFilter<TagDescriptionsDocumentFilter>();
            #endregion
            //忽略部分内容
        }
        );
}

请求http://localhost:5000/v1/swaggerapi.json,在返回结果中能够看到如下部分结构:

{
    //忽略无关项
    "tags": [
    {
      "name": "Pages",
      "description": "分页类"
    },
    {
      "name": "Tests",
      "description": "测试类"
    }
  ]
}

后续文章将讲解为Swagger添加安全验证。



相关文章
|
8天前
|
开发框架 .NET 开发者
简化 ASP.NET Core 依赖注入(DI)注册-Scrutor
Scrutor 是一个简化 ASP.NET Core 应用程序中依赖注入(DI)注册过程的开源库,支持自动扫描和注册服务。通过简单的配置,开发者可以轻松地从指定程序集中筛选、注册服务,并设置其生命周期,同时支持服务装饰等高级功能。适用于大型项目,提高代码的可维护性和简洁性。仓库地址:&lt;https://github.com/khellang/Scrutor&gt;
29 5
|
26天前
|
开发框架 .NET C#
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
38 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
|
16天前
|
开发框架 缓存 .NET
GraphQL 与 ASP.NET Core 集成:从入门到精通
本文详细介绍了如何在ASP.NET Core中集成GraphQL,包括安装必要的NuGet包、创建GraphQL Schema、配置GraphQL服务等步骤。同时,文章还探讨了常见问题及其解决方法,如处理复杂查询、错误处理、性能优化和实现认证授权等,旨在帮助开发者构建灵活且高效的API。
24 3
|
2月前
|
开发框架 JavaScript 前端开发
一个适用于 ASP.NET Core 的轻量级插件框架
一个适用于 ASP.NET Core 的轻量级插件框架
|
3月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
48 7
|
3月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
75 0
|
4月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
56 0
|
4月前
|
开发框架 前端开发 安全
ASP.NET MVC 如何使用 Form Authentication?
ASP.NET MVC 如何使用 Form Authentication?
|
4月前
|
开发框架 .NET
Asp.Net Core 使用X.PagedList.Mvc.Core分页 & 搜索
Asp.Net Core 使用X.PagedList.Mvc.Core分页 & 搜索
143 0
|
7月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
212 0