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

如何在.NET 8中用System.Text.Json反序列化键不同结构相同的对象?

在.NET 8中使用System.Text.Json将字典结构的Cart反序列化为集合

问题描述

给定的JSON数据中,cart字段是一个以商品ID为键、商品详情为值的字典结构,需要将其反序列化为包含CartItem数组的Cart类结构,目标C#类定义大致如下,需用.NET 8的System.Text.Json.Serialization实现该反序列化。

示例JSON

{"checksum": "8ea325b368df5f2994e3c6da022e52db","totalPrice": {"amount": "71.98","symbol": "$","code": "USD","isZero": false,"rawAmount": 7198,"formattedAmount": "71.98","full": "$ 71.98","for_email": "$ 71.98"},"cart": {"1345516108": {"id": 1345516108,"price": {"currency": "USD","amount": "11.99","baseAmount": "29.99","finalAmount": "11.99","isDiscounted": true,"discountPercentage": 60,"discountDifference": "18.00","symbol": "$","isFree": false,"discount": 60,"isBonusStoreCreditIncluded": false,"bonusStoreCreditAmount": "0.00","promoId": "weekly_deals_3_november"},"timeAdded": 1700141748,"availability": {"isAvailable": true,"isAvailableInAccount": true},"isDiscounted": true,"isInDevelopment": false,"releaseDate": 1659560400,"salesVisibility": {"isActive": true,"fromObject": {"date": "2022-08-04 19:55:00.000000","timezone_type": 3,"timezone": "Europe/Nicosia"},"from": 1659632100,"toObject": {"date": "2037-12-31 23:59:59.000000","timezone_type": 3,"timezone": "Europe/Nicosia"},"to": 2145909599},"buyable": true,"title": "Hard West 2","url": "/en/game/hard_west_2","supportUrl": "/support/","forumUrl": null,"worksOn": {"Windows": true,"Mac": false,"Linux": false},"category": "Role-playing","originalCategory": null,"rating": 0,"type": 1,"isComingSoon": false,"isPriceVisible": true,"isMovie": false,"isGame": true,"slug": null,"isWishlistable": true,"extraInfo": [],"ageLimit": 0},"1456460669": {"id": 1456460669,"price": {"currency": "USD","amount": "59.99","baseAmount": "59.99","finalAmount": "59.99","isDiscounted": false,"discountPercentage": 0,"discountDifference": "0.00","symbol": "$","isFree": false,"discount": 0,"isBonusStoreCreditIncluded": false,"bonusStoreCreditAmount": "0.00","promoId": null},"timeAdded": 1700141758,"availability": {"isAvailable": true,"isAvailableInAccount": true},"isDiscounted": false,"isInDevelopment": false,"releaseDate": 1691010000,"salesVisibility": {"isActive": true,"fromObject": {"date": "2020-10-06 19:50:00.000000","timezone_type": 3,"timezone": "Europe/Nicosia"},"from": 1602003000,"toObject": {"date": "2037-12-31 23:59:59.000000","timezone_type": 3,"timezone": "Europe/Nicosia"},"to": 2145909599},"buyable": true,"title": "Baldur's Gate 3","url": "/en/game/baldurs_gate_iii","supportUrl": "/support/","forumUrl": null,"worksOn": {"Windows": true,"Mac": true,"Linux": false},"category": "Role-playing","originalCategory": null,"rating": 39,"type": 1,"isComingSoon": false,"isPriceVisible": true,"isMovie": false,"isGame": true,"slug": null,"isWishlistable": true,"extraInfo": [],"ageLimit": 0}},"overallAgeLimit": 0}

目标C#类结构

public class Rootobject
{
    public string checksum { get; set; }
    public Totalprice totalPrice { get; set; }
    public Cart cart { get; set; }
    public int overallAgeLimit { get; set; }
}

public class Totalprice
{
    public string amount { get; set; }
    public string symbol { get; set; }
    public string code { get; set; }
    public bool isZero { get; set; }
    public int rawAmount { get; set; }
    public string formattedAmount { get; set; }
    public string full { get; set; }
    public string for_email { get; set; }
}

public class Cart
{
    public CartItem[] cartItems { get; set; }
}

public class CartItem
{
    public int id { get; set; }
    public Price price { get; set; }
    public int timeAdded { get; set; }
    public Availability availability { get; set; }
    public bool isDiscounted { get; set; }
    public bool isInDevelopment { get; set; }
    public int releaseDate { get; set; }
    public SalesVisibility salesVisibility { get; set; }
    public bool buyable { get; set; }
    public string title { get; set; }
    public string url { get; set; }
    public string supportUrl { get; set; }
    public string forumUrl { get; set; }
    public WorksOn worksOn { get; set; }
    public string category { get; set; }
    public object originalCategory { get; set; }
    public int rating { get; set; }
    public int type { get; set; }
    public bool isComingSoon { get; set; }
    public bool isPriceVisible { get; set; }
    public bool isMovie { get; set; }
    public bool isGame { get; set; }
    public object slug { get; set; }
    public bool isWishlistable { get; set; }
    public object[] extraInfo { get; set; }
    public int ageLimit { get; set; }
}

public class Price
{
    public string currency { get; set; }
    public string amount { get; set; }
    public string baseAmount { get; set; }
    public string finalAmount { get; set; }
    public bool isDiscounted { get; set; }
    public int discountPercentage { get; set; }
    public string discountDifference { get; set; }
    public string symbol { get; set; }
    public bool isFree { get; set; }
    public int discount { get; set; }
    public bool isBonusStoreCreditIncluded { get; set; }
    public string bonusStoreCreditAmount { get; set; }
    public string promoId { get; set; }
}

public class Availability
{
    public bool isAvailable { get; set; }
    public bool isAvailableInAccount { get; set; }
}

public class SalesVisibility
{
    public bool isActive { get; set; }
    public FromObject fromObject { get; set; }
    public int from { get; set; }
    public ToObject toObject { get; set; }
    public int to { get; set; }
}

public class FromObject
{
    public string date { get; set; }
    public int timezone_type { get; set; }
    public string timezone { get; set; }
}

public class ToObject
{
    public string date { get; set; }
    public int timezone_type { get; set; }
    public string timezone { get; set; }
}

public class WorksOn
{
    public bool Windows { get; set; }
    public bool Mac { get; set; }
    public bool Linux { get; set; }
}

解决方案

可以通过自定义Json转换器实现该需求,具体步骤如下:

1. 创建自定义Cart转换器

实现JsonConverter<Cart>,在反序列化时将JSON中的字典结构转为CartItem数组:

public class CartConverter : JsonConverter<Cart>
{
    public override Cart Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 将JSON中的cart对象反序列化为字典
        var cartDictionary = JsonSerializer.Deserialize<Dictionary<string, CartItem>>(ref reader, options);
        
        // 将字典的值转为数组并返回Cart实例
        return new Cart
        {
            cartItems = cartDictionary?.Values.ToArray() ?? Array.Empty<CartItem>()
        };
    }

    public override void Write(Utf8JsonWriter writer, Cart value, JsonSerializerOptions options)
    {
        // 如果需要序列化,可将数组转回字典(以CartItem.Id为键)
        var cartDictionary = value.cartItems?.ToDictionary(item => item.id.ToString()) ?? new Dictionary<string, CartItem>();
        JsonSerializer.Serialize(writer, cartDictionary, options);
    }
}

2. 为Cart类添加转换器特性

在Cart类上标记[JsonConverter]特性,指定使用自定义转换器:

[JsonConverter(typeof(CartConverter))]
public class Cart
{
    public CartItem[] cartItems { get; set; }
}

3. 执行反序列化

使用JsonSerializer.Deserialize方法完成反序列化:

string json = "你的JSON字符串";
var root = JsonSerializer.Deserialize<Rootobject>(json);

此时root.cart.cartItems将包含JSON中cart字段下的所有商品项。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 14:15:57