正确吗?,c#,swagger,openapi,openapi-generator"/>

首页 > 解决方案 > 如何让 OpenApi Generator 转换字典正确吗?

问题描述

现在我的 Api 返回一个带有Dictionary<int, string>属性的模型:

public Dictionary<int, string> Subdivisions { get; set; }

当我运行 OpenApi Generator 时,输出类有

public Dictionary<string, string> Subdivisions { get; set; }

我知道 JSON 规范不允许整数键,但这确实搞砸了期望 <int, string> 的 API 的消费者。

我能做些什么来确保我的输出类有Dictionary<int, string>而不是Dictionary<string, string>

标签: c#swaggeropenapiopenapi-generator

解决方案


由于 Swagger/OpenAPI 定义特定于 REST,它们可能会继续支持可以用 JSON 表示的模型。JSON 是一种与语言无关的序列化格式,支持对象和集合,但它没有方法或实际实现。REST 提供了对服务器的 JSON 副本进行变异的方法,然后要求使用者根据需要解释响应。由于 JSON 中没有 Map,IDictionary 的默认设置是将其序列化为对象,使用它的键作为属性名称——好处是类似于 map 的查找功能,但代价是属性名称必须是字符串。

那么,Dictionary<int,string>在有效的 JSON 中会是什么样子?使用自定义序列化器和反序列化器,我们可以期待一个 Key-Value-Pair 对象列表:

[
    {"key":1, "value": "one"},
    {"key":2, "value": "two"}
]

您将使用此 KVP 模型发布 REST 操作,然后在您的 API 上放置一个自定义转换器,以将此 KVP 列表与字典进行转换。这将符合 OAS/JSON 并允许期望 <int, string> 的 API/服务的非 REST 消费者。有几个例子可以说明如何做到这一点:

C# JSON 自定义序列化 https://www.newtonsoft.com/json/help/html/SerializingCollections.htm

但是,如果您真的需要从不符合标准的 swagger 定义生成代码,则可以覆盖生成器以满足您的需求。将其视为一个警告,即您的实现不符合常规,并且您在此代码生成中所做的所有努力都可能因次要版本而被撤消。最好找到一种方法朝着社区的方向前进,以使您的解决方案具有最长的可行性。

话虽如此,生成器是一个简单的 Java 程序,它使用 Mustache 模板读取规范并输出文本文件。“CodeGen”类按照语言特定的逻辑将规范解析为数组,然后“Mustache”模板在数组上应用无逻辑逻辑以生成代码。通过阅读 Java 作为指南,我通常能够通过仅修改 Mustache 模板或配置来生成我的自定义类。不幸的是,对于您的情况,returnTypefor an Operation 仅支持List 或 primitive,因此如果您希望生成的 API 返回字典,则需要修改 CodeGen Java。如果你去这么远的上游,一定要带上桨!

这里是为 Maps 设置 IDictonary 类型的地方。 这里是一般设置的地方,这里是针对 C# 的。这是创建模型属性的 Mustache,也是创建 API操作的方式。


推荐阅读