Skip to content

Commit dd38f31

Browse files
committed
remove xml , support object to any in openapi
1 parent c448381 commit dd38f31

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

SimApiExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ public static IServiceCollection AddSimApi(this IServiceCollection builder,
127127
x.OperationFilter<SimApiResponseOperationFilter>();
128128
x.OperationFilter<SimApiSignOperationFilter>();
129129
x.OperationFilter<AesBodyOperationFilter>();
130+
x.SchemaFilter<GlobalDynamicObjectSchemaFilter>();
130131
if (simApiOptions.EnableSimApiAuth)
131132
{
132133
x.OperationFilter<SimApiAuthOperationFilter>();
@@ -239,7 +240,6 @@ public static IServiceCollection AddSimApi(this IServiceCollection builder,
239240
if (simApiOptions.EnableSimApiResponseFilter)
240241
{
241242
builder.AddControllers(opt => opt.Filters.Add<SimApiResponseFilter>())
242-
.AddXmlSerializerFormatters()
243243
.AddJsonOptions(opt =>
244244
{
245245
opt.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using System;
2+
using Microsoft.OpenApi.Models;
3+
using Swashbuckle.AspNetCore.SwaggerGen;
4+
using System.Collections;
5+
using System.Collections.Generic;
6+
using System.Reflection;
7+
using Microsoft.OpenApi.Any;
8+
9+
namespace SimApi.SwaggerFilters;
10+
11+
public class GlobalDynamicObjectSchemaFilter : ISchemaFilter
12+
{
13+
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
14+
{
15+
if (!IsDynamicObjectType(context.Type)) return;
16+
schema.AdditionalPropertiesAllowed = true;
17+
schema.AdditionalProperties = new OpenApiSchema
18+
{
19+
Type = "object", // 表示 value 可以是任意类型(兼容所有类型)
20+
Nullable = true
21+
};
22+
23+
// 2. 覆盖默认示例,使用包含多种类型的示例
24+
schema.Example = CreateMultiTypeExample();
25+
}
26+
27+
// 判断是否为需要处理的“动态对象”类型
28+
private bool IsDynamicObjectType(Type? type)
29+
{
30+
if (type == null) return false;
31+
if (typeof(IDictionary).IsAssignableFrom(type) ||
32+
(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>)))
33+
{
34+
return true;
35+
}
36+
if (type == typeof(object))
37+
{
38+
return true;
39+
}
40+
return type.Name.Contains("AnonymousType") && type.Namespace == null;
41+
}
42+
43+
// 创建包含多种类型的示例(覆盖默认的 string 示例)
44+
private OpenApiObject CreateMultiTypeExample()
45+
{
46+
return new OpenApiObject
47+
{
48+
["stringProp"] = new OpenApiString("example string"), // 字符串
49+
["numberProp"] = new OpenApiInteger(123), // 数字
50+
["boolProp"] = new OpenApiBoolean(true), // 布尔值
51+
["objectProp"] = new OpenApiObject // 嵌套对象
52+
{
53+
["nestedKey"] = new OpenApiString("nested value")
54+
},
55+
["arrayProp"] = new OpenApiArray // 数组
56+
{
57+
new OpenApiInteger(1),
58+
new OpenApiString("two")
59+
}
60+
};
61+
}
62+
}

0 commit comments

Comments
 (0)