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

.NET 7 API如何移除JSON请求的data包装类实现单类参数绑定?

.NET 7 API 跳过外层data包装直接绑定到单个类的解决方案

方案一:使用JsonPropertyName指定嵌套路径(单个类场景)

.NET 7 默认使用 System.Text.Json 进行JSON序列化/反序列化,它支持通过点路径指定属性对应的JSON节点位置。你只需要将原来的 [DataMember] 替换为 [JsonPropertyName],并指定完整的嵌套路径即可:

using System.Text.Json.Serialization;

public class ReserveRequest
{
    [JsonPropertyName("data.productId")]
    public string ProductId { get; set; }

    [JsonPropertyName("data.dateTime")]
    public string DateTime { get; set; }

    [JsonPropertyName("data.bookingItems")]
    public List<BookingItem> BookingItems { get; set; }
}

public class BookingItem
{
    [JsonPropertyName("category")]
    public string Category { get; set; }

    [JsonPropertyName("count")]
    public int Count { get; set; }
}

控制器方法直接接收 ReserveRequest 即可完成绑定:

[HttpPost]
public IActionResult Reserve([FromBody] ReserveRequest request)
{
    // 业务逻辑处理
    return Ok();
}

方案二:自定义JSON转换器(全局统一处理场景)

如果所有POST请求都带有外层 data 包装,推荐使用自定义JSON转换器,一次性解决所有类的绑定问题,无需逐个修改属性:

1. 实现转换器

using System.Text.Json;
using System.Text.Json.Serialization;

public class DataWrapperConverter<T> : JsonConverter<T>
{
    public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using JsonDocument doc = JsonDocument.ParseValue(ref reader);
        // 提取外层的data节点
        JsonElement dataElement = doc.RootElement.GetProperty("data");
        // 将data节点内容反序列化为目标类型
        return dataElement.Deserialize<T>(options);
    }

    public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
    {
        // 如果需要返回的JSON也带data包装,保留此方法;否则可以抛出NotImplementedException
        writer.WriteStartObject();
        writer.WritePropertyName("data");
        JsonSerializer.Serialize(writer, value, options);
        writer.WriteEndObject();
    }
}

2. 注册转换器

方式一:全局注册(所有指定类型生效)

在 Program.cs 中配置JSON选项:

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        // 为ReserveRequest添加转换器
        options.JsonSerializerOptions.Converters.Add(new DataWrapperConverter<ReserveRequest>());
        // 如有其他需要处理的请求类,继续添加
        // options.JsonSerializerOptions.Converters.Add(new DataWrapperConverter<AnotherRequest>());
    });

方式二:单个类上标注(仅当前类生效)

直接在 ReserveRequest 类上添加转换器属性:

[JsonConverter(typeof(DataWrapperConverter<ReserveRequest>))]
public class ReserveRequest
{
    [JsonPropertyName("productId")]
    public string ProductId { get; set; }

    [JsonPropertyName("dateTime")]
    public string DateTime { get; set; }

    [JsonPropertyName("bookingItems")]
    public List<BookingItem> BookingItems { get; set; }
}

注意事项

  • 替换旧属性:.NET 7 默认使用 System.Text.Json,原代码中的 [DataMember] 是 DataContractSerializer(WCF使用)的属性,不再适用,需替换为 System.Text.Json.Serialization.JsonPropertyName。
  • 异常处理:如果请求JSON中不存在 data 节点,两种方案都会抛出异常,可根据需求在转换器中添加空值判断逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 01:39:56