如何使用 Swashbuckle.AspNetCore 将自定义泛型类型公开为 Swagger 架构中的字符串

2024-03-28

我有一个自定义泛型类型,大致如下所示:

public struct Foo<T>
{
    public int Value { get; }
    public string Signature { get; }
    public Type Type { get; }
}

该类型用于请求和响应主体以及控制器操作参数。一切都经过配置,以便将其序列化为字符串,并且它可以与模型绑定和 JSON 序列化配合良好。该类型有一个TypeConverter与之关联,它负责将其与字符串相互转换。

然而,Swagger 模式仍然将其表示为具有 3 个属性的对象。这Type财产也扩大了,这拉动了所有System.Reflection直接或间接暴露的类型Type.

如何避免这种情况并将我的类型公开为字符串?


尝试的第一个解决方案:使用MapType

我尝试使用MapType;如果我指定泛型类型参数,它可以正常工作,但不适用于开放泛型类型:

c.MapType(typeof(Foo<Something>), () => new OpenApiSchema { Type = "string" }); // Works
c.MapType(typeof(Foo<>), () => new OpenApiSchema { Type = "string" }); // Doesn't work

我如何将映射应用到Foo<T>,对于任何T?


目前的解决方法

到目前为止,我唯一的解决方法非常丑陋:

class SchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.Type is Type type &&
            type.IsGenericType &&
            !type.IsGenericTypeDefinition &&
            type.GetGenericTypeDefinition() == typeof(Foo<>))
        {
            schema.Type = "string";
            schema.Properties.Clear();
        }
        else if (context.Type?.FullName.StartsWith("System.", StringComparison.Ordinal) is true
            && context.SchemaRepository.TryGetIdFor(context.Type, out var schemaId))
        {
            DocFilter.SchemaIdsToRemove.Add(schemaId);
        }
    }
}

class DocFilter : IDocumentFilter
{
    public static readonly HashSet<string> SchemaIdsToRemove = new HashSet<string>();

    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        foreach (var schemaId in SchemaIdsToRemove)
        {
            swaggerDoc.Components.Schemas.Remove(schemaId);
        }
    }
}

我不确定你想做什么。因为如果我正确理解您的场景,最好的事情就是为 Foo 泛型类型的每个基础类型公开一个架构定义,那么代码将类似于:

public class FooSchemaFilter : ISchemaFilter
    {
        public void Apply(OpenApiSchema schema, SchemaFilterContext context)
        {
            if (context.Type.IsGenericType && context.Type.GetGenericTypeDefinition() == typeof(Foo<>))
            {
                var argumentType = context.Type.GetGenericArguments().First();
                var argumentSchema = context.SchemaGenerator.GenerateSchema(argumentType, context.SchemaRepository);
                var baseSchemaName = $"{argumentType.Name}Foo";
                var baseSchema = new OpenApiSchema()
                {
                    Required = new SortedSet<string>() { "type" },
                    Type = "object",
                    Properties = new Dictionary<string, OpenApiSchema> {
                        { "type", argumentSchema }
                };
                context.SchemaRepository.AddDefinition(baseSchemaName, baseSchema);
                schema.Type = "string";
                schema.Reference = new OpenApiReference { Id = $"{baseSchemaName}", Type = ReferenceType.Schema };
            }
        }
    }

如果您还需要其他属性,请将它们包含在基本架构中。 这将为每种类型创建一个新架构,但它应该反序列化为您的泛型类型。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Swashbuckle.AspNetCore 将自定义泛型类型公开为 Swagger 架构中的字符串 的相关文章

随机推荐

  • Xamarin 表单:如何复制条目值?

    我想从我的应用程序复制一个值并将其粘贴到同一应用程序的任何其他位置或应用程序外部 我已经在寻找答案这个线程 https stackoverflow com questions 3546016 how to copy data to clip
  • 验证/提交错误:应用程序未通过协同设计验证

    我有许多几乎相同的应用程序 除了一些常量 图像和 sqllite 数据库文件 我之前提交它们时从未遇到过任何问题 但是今天其中一个更新在验证 提交时出现以下错误 注意 我过去已经更新过此应用程序 没有任何问题 应用程序未通过协同设计验证 签
  • 使用 LINQ 连接两个不同类型的列表

    是否可以连接两个不同类型的列表 string left A B C int right 1 2 3 var result left Concat right 上面的代码显然有一个类型错误 如果类型匹配 例如都是整数或字符串 它就可以工作 p
  • 如何在Linux中从动态库(libsample.so)生成导入库(libsample.a)

    在Linux上创建动态库后我想生成一个导入库 a 来自动态库 所以 我该怎么做 实际上 linux中的动态库不需要 导入库 导入库 是Windows中的想法 当你构建一个dll时 vs也会给你一个lib文件作为 导入库 或者你必须通过一些
  • 如何从 ResultSet 填充 JTable?

    I call getnPrintAllData 按确定按钮后的方法 public class DatabaseSQLiteConnection Connection conn null PreparedStatement statement
  • BeautifulSoup 在按复合类名搜索时返回空列表

    使用正则表达式按复合类名搜索时 BeautifulSoup 返回空列表 Example import re from bs4 import BeautifulSoup bs a class name single name692 href
  • 编写 Prolog 谓词的最佳实践是什么,以便它以指定参数的不同方式工作

    我正在尝试实现一些简单的谓词 例如 my length 或 my append 如果我们事先知道我们想要找到列表的长度 或者我们想要附加两个列表 这对我来说很容易 即我知道什么是输入 什么是输出 在 Prolog 中 可以用其他方式做事 如
  • Selenium findElements() 多次返回第一个元素的同一实例

    我需要获取所有文章标题的列表 但由于某种原因 Selenium 返回了文章 WebElement 的同一实例 3 次 网页 HTML 如下所示 div class site content clearfix div class contai
  • 如何使用 uibinder 创建带有子级的 gwt 复合组件?

    我想创建一个组件来装饰它的子组件 例如 mycomponent ui xml
  • formData.has() 不是一个函数[重复]

    这个问题在这里已经有答案了 我正在尝试执行简单的 ajax 文件上传 但收到 未捕获的类型错误 formData has 不是函数 如果我还注释掉 formData has 检查函数并将其替换为 formData append myResu
  • MS Azure Web 角色 - 如何指定 Webroot 驱动器存储大小

    我正在开发一个非常大且复杂的企业 Web 应用程序 托管在 azure 中 注意到 Web 根目录位于 E 盘 我还注意到 C 驱动器的大小为 490GB 但有趣的是 E盘上的Web根目录大小只有1GB 有什么方法可以指定您要安装的驱动器
  • 如何保护此代码免遭 SQL 注入?有点困惑

    我已经阅读了各种来源 但我不确定如何将它们实现到我的代码中 我想知道是否有人可以帮我快速完成它 一旦我在代码中被展示如何做到这一点 我想我就能学会它 这是来自我在网上找到的 AJAX 自动完成 尽管我看到它由于 queryString 或其
  • 使用php将图像保存到服务器

    嘿 我有以下脚本 基本上是一个闪存文件向它发送一些数据 它创建一个图像 然后为用户打开一个另存为对话框 以便他们可以将图像保存到系统中 问题来了 如何我还要将图像保存到我的服务器吗
  • Laravel - 多对多多态关系

    我正在努力反对 Laravel 5 7 中的多态关系定义 数据情况如下 我有一个用户模型 一个产品模型和一个销售模型 我基本上想为我的用户构建一个愿望清单 它可以包含商品和产品 并且我希望在那里有一个多态关系 因为我将不得不添加新类型的东西
  • AWS S3 中有乐观锁吗?

    我在 s3 中有一个 excel 文件 由于不同的程序读取和写入它 我需要保证每个程序都写入它们读取的版本 S3仅保证新创建对象的读后一致性 以及覆盖和删除对象的最终一致性 如果您的 Excel 文件足够小 小于 400kb 您可以将其存储
  • TYPO3 表单多复选框部分

    我尝试编辑核心文件 form Resources Private Frontend Partials Field Field html 以更改前端中的 html 输出 如果我更改该文件 它不会产生任何影响 如果我更改核心文件 form Re
  • 同时显示两个片段

    From FragmentPagerAdapter in case 0我实例化了fragment A我想显示的这个片段显示里面的两个片段frag A 视图未显示 我的 FragmentPagerAdapter 由主类调用来填充 viewpa
  • 如何使用 VS 2008 和 IE 完全禁用 JavaScript 错误

    我试图防止 VS 因 JS 错误而中断 我有以下设置 在 IE 下 Tools gt Internet Settings gt Advanced tab gt Browsing Disable script debugging Intern
  • Jquery Ajax CORS + HttpOnly Cookie

    我已经在我当前的项目中使用了 CORS 尽管我似乎无法正常工作的一件事是 cookie 现在我得到了 cookie 服务器发出它并将其发送下来 firefox 接受它 我可以在 firebug cookies 部分看到它 然而 当我对该服务
  • 如何使用 Swashbuckle.AspNetCore 将自定义泛型类型公开为 Swagger 架构中的字符串

    我有一个自定义泛型类型 大致如下所示 public struct Foo