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

如何让C#/.NET Core自定义类/结构体在Swagger中呈现为值类型?

解决方案

要让自定义类/结构体在Swagger里呈现为单一值类型(类似DateTime的效果),需要同时搞定JSON序列化逻辑和Swagger Schema的识别配置,下面是具体步骤:

1. 实现自定义类型的JSON序列化转换

首先得让JSON序列化器把你的自定义类型转换成单一值(比如字符串、数字),而非展开它的内部属性。以.NET Core默认的System.Text.Json为例:

假设我们自定义一个Email结构体:

public readonly struct Email
{
    public string Value { get; }

    public Email(string value)
    {
        if (!value.Contains("@"))
            throw new ArgumentException("无效的邮箱格式");
        Value = value;
    }

    public override string ToString() => Value;

    // 可选:实现隐式转换,简化类型使用
    public static implicit operator string(Email email) => email.Value;
    public static implicit operator Email(string value) => new Email(value);
}

接着写对应的JSON转换器,控制序列化/反序列化行为:

public class EmailJsonConverter : JsonConverter<Email>
{
    public override Email Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return new Email(reader.GetString()!);
    }

    public override void Write(Utf8JsonWriter writer, Email value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.Value);
    }
}

在Program.cs里注册这个转换器:

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Converters.Add(new EmailJsonConverter());
    });

2. 配置Swagger识别自定义类型为值类型

此时序列化逻辑已正常,但Swagger仍会把Email识别为带Value属性的对象,需要修改Swagger的Schema定义:

方式一:使用SchemaFilter

实现一个SchemaFilter来修正Schema:

public class EmailSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.Type == typeof(Email))
        {
            schema.Type = "string";
            schema.Format = "email"; // 可选:指定格式,让Swagger识别为邮箱类型
            schema.Properties.Clear();
            schema.Example = new OpenApiString("user@example.com");
        }
    }
}

在Swagger配置中注册这个Filter:

builder.Services.AddSwaggerGen(c =>
{
    c.SchemaFilter<EmailSchemaFilter>();
    // 其他Swagger配置...
});

方式二:用属性简化配置

如果不想写Filter,可直接给自定义类型添加SwaggerSchema属性(需引用Swashbuckle.AspNetCore.Annotations包):

using Swashbuckle.AspNetCore.Annotations;

[SwaggerSchema(Type = "string", Format = "email", Example = "user@example.com")]
public readonly struct Email
{
    // 结构体内容不变...
}

3. 验证效果

定义一个测试接口:

[HttpPost]
public IActionResult SendEmail([FromBody] EmailRequest request)
{
    return Ok($"发送邮件到:{request.Recipient}");
}

public class EmailRequest
{
    public Email Recipient { get; set; }
}

此时Swagger文档里的EmailRequest会显示为:

{
  "recipient": "user@example.com"
}

完全和DateTime的展示逻辑一致,不会展开成嵌套属性结构。


内容的提问来源于stack exchange,提问作者Ben Dickey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 13:20:26