如何让SwaggerUI将自定义Record类型识别为字符串类型?
解决方案
1. 定义自定义特性[JsonConvertAs]
先创建特性类,用来标记类型需要被序列化为指定目标类型:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] public class JsonConvertAsAttribute : Attribute { public Type TargetType { get; } public JsonConvertAsAttribute(Type targetType) { TargetType = targetType; } }
2. 实现通用Json转换器
基于特性编写通用转换器,处理类型的序列化/反序列化逻辑:
public class ConvertAsJsonConverter : JsonConverterFactory { public override bool CanConvert(Type typeToConvert) { return typeToConvert.GetCustomAttribute<JsonConvertAsAttribute>() != null; } public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) { var attribute = typeToConvert.GetCustomAttribute<JsonConvertAsAttribute>(); var converterType = typeof(ConvertAsJsonConverter<>).MakeGenericType(typeToConvert, attribute.TargetType); return (JsonConverter)Activator.CreateInstance(converterType); } } public class ConvertAsJsonConverter<TOriginal, TTarget> : JsonConverter<TOriginal> { public override TOriginal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var value = JsonSerializer.Deserialize<TTarget>(ref reader, options); return (TOriginal)Convert.ChangeType(value, typeof(TOriginal)); } public override void Write(Utf8JsonWriter writer, TOriginal value, JsonSerializerOptions options) { var targetValue = (TTarget)Convert.ChangeType(value, typeof(TTarget)); JsonSerializer.Serialize(writer, targetValue, options); } }
3. 标记ExampleProp并保留隐式转换
给你的record类型加上特性,同时保留已有的隐式转换逻辑:
[JsonConvertAs(typeof(string))] public record ExampleProp(string Value) { public static implicit operator string(ExampleProp prop) => prop.Value; public static implicit operator ExampleProp(string value) => new ExampleProp(value); }
4. 实现Swagger Schema过滤器
让Swagger识别特性,将目标类型的Schema替换到标记类型上:
public class ConvertAsSchemaFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { var attribute = context.Type.GetCustomAttribute<JsonConvertAsAttribute>(); if (attribute == null) return; var targetSchema = context.SchemaGenerator.GenerateSchema(attribute.TargetType, context.SchemaRepository); schema.Type = targetSchema.Type; schema.Format = targetSchema.Format; schema.Example = targetSchema.Example ?? new OpenApiString("string"); schema.Nullable = targetSchema.Nullable; schema.Properties.Clear(); schema.AdditionalPropertiesAllowed = false; } }
5. 注册服务到ASP.NET Core
在Program.cs中注册Json转换器和Swagger过滤器:
builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new ConvertAsJsonConverter()); }); builder.Services.AddSwaggerGen(options => { options.SchemaFilter<ConvertAsSchemaFilter>(); });
配置完成后,Swagger UI会将ExampleProp识别为string类型,示例值显示为"string",同时JSON序列化/反序列化逻辑保持正常。通过[JsonConvertAs]特性还能快速将其他支持隐式转换的类型映射到目标类型(如int、Guid等)。
内容的提问来源于stack exchange,提问作者filimonic
相关产品推荐
相关产品推荐

