You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 20:39:55