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添加安全验证。



相关文章
|
1月前
|
存储 开发框架 JSON
ASP.NET Core OData 9 正式发布
【10月更文挑战第8天】Microsoft 在 2024 年 8 月 30 日宣布推出 ASP.NET Core OData 9,此版本与 .NET 8 的 OData 库保持一致,改进了数据编码以符合 OData 规范,并放弃了对旧版 .NET Framework 的支持,仅支持 .NET 8 及更高版本。新版本引入了更快的 JSON 编写器 `System.Text.UTF8JsonWriter`,优化了内存使用和序列化速度。
|
1月前
mcr.microsoft.com/dotnet/core/aspnet:2.1安装libgdiplus
mcr.microsoft.com/dotnet/core/aspnet:2.1安装libgdiplus
29 1
|
2月前
|
开发框架 监控 前端开发
在 ASP.NET Core Web API 中使用操作筛选器统一处理通用操作
【9月更文挑战第27天】操作筛选器是ASP.NET Core MVC和Web API中的一种过滤器,可在操作方法执行前后运行代码,适用于日志记录、性能监控和验证等场景。通过实现`IActionFilter`接口的`OnActionExecuting`和`OnActionExecuted`方法,可以统一处理日志、验证及异常。创建并注册自定义筛选器类,能提升代码的可维护性和复用性。
|
2月前
|
开发框架 .NET 中间件
ASP.NET Core Web 开发浅谈
本文介绍ASP.NET Core,一个轻量级、开源的跨平台框架,专为构建高性能Web应用设计。通过简单步骤,你将学会创建首个Web应用。文章还深入探讨了路由配置、依赖注入及安全性配置等常见问题,并提供了实用示例代码以助于理解与避免错误,帮助开发者更好地掌握ASP.NET Core的核心概念。
92 3
|
1月前
|
开发框架 JavaScript 前端开发
一个适用于 ASP.NET Core 的轻量级插件框架
一个适用于 ASP.NET Core 的轻量级插件框架
|
2月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
41 7
|
2月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
58 0
|
3月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
47 0
|
3月前
|
开发框架 前端开发 安全
ASP.NET MVC 如何使用 Form Authentication?
ASP.NET MVC 如何使用 Form Authentication?
|
3月前
|
开发框架 .NET
Asp.Net Core 使用X.PagedList.Mvc.Core分页 & 搜索
Asp.Net Core 使用X.PagedList.Mvc.Core分页 & 搜索
124 0

热门文章

最新文章