Swagger OpenAPI字符串数组Tags反序列化失败问题及解决
问题场景
我需要从Swashbuckle生成的JSON中反序列化OpenApiPathItem集合,但对象内的集合结果为null。排查后发现问题出在Operation对象的Tags参数上。
相关JSON示例
{ "openapi": "3.0.1", "info": { "title": "MyApp", "version": "1.0" }, "paths": { "/api/v1/my-controller/{myParam}": { "get": { "tags": [ "MyTag" ], "parameters": [ { "name": "myParam", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Success" } } } } } }
错误信息
Newtonsoft.Json.JsonSerializationException: Error converting value "MyTag" to type 'Microsoft.OpenApi.Models.OpenApiTag'. Path 'tags[0]'
我的反序列化代码
var convert = JObject.Parse(swaggerJson); foreach (KeyValuePair<string, JToken> jToken in (JObject)convert["paths"]) { var operationObj = jToken.Value["get"].ToString(); var result = JsonConvert.DeserializeObject<OpenApiOperation>(operationObj, new JsonSerializerSettings() { MetadataPropertyHandling = MetadataPropertyHandling.Ignore, NullValueHandling = NullValueHandling.Ignore }); }
Swagger中间件配置
builder.Services.AddSwaggerGen().AddSwaggerGenNewtonsoftSupport();
网上很多Swagger JSON示例里tags都是字符串数组,但我没找到其他人遇到这个问题的记录。
解决方法(更新)
感谢@Helen的提示,了解到OpenAPI架构和JSON的结构不完全兼容,导致Newtonsoft反序列化器无法正确转换。我写了一个临时解决方法,供其他开发者参考:
重写相关类
internal class OpenApiPathItemOverride : OpenApiPathItem { public new IDictionary<OperationType, OpenApiOperationOverride> Operations { get; set; } = new Dictionary<OperationType, OpenApiOperationOverride>(); } internal class OpenApiOperationOverride : OpenApiOperation { public new IList<OpenApiTagOverride> Tags { get; set; } = new List<OpenApiTagOverride>(); } internal class OpenApiTagOverride : OpenApiTag { public OpenApiTagOverride(string name) { Name = name; } public static implicit operator OpenApiTagOverride(string name) => new OpenApiTagOverride(name); }
使用方式
var convert = JObject.Parse(swaggerJson); Dictionary<string, OpenApiOperationOverride> paths = new(); foreach (KeyValuePair<string, JToken> jToken in (JObject)convert["paths"]) { var pathName = jToken.Key; OpenApiOperationOverride pathObj = null; Dictionary<string, OpenApiOperationOverride> operation = jToken.Value.ToObject<Dictionary<string, OpenApiOperationOverride>>(); }
内容的提问来源于stack exchange,提问作者slasky
相关产品推荐
相关产品推荐

