如何将特定的Json节点反序列化为Dictionary<string,object>?

4

我有一个JSON响应,长这样:

{
"success": true,
"more": false,
"results_html": "a lot of html in here",
"listinginfo": {
    "637640274112277168": {
        "listingid": "637640274112277168",
        "price": 50,
        "fee": 7,
        "publisher_fee_app": 730,
        "publisher_fee_percent": "0.10000000149011612",
        "currencyid": "2005",
        "steam_fee": 2,
        "publisher_fee": 5,
        "converted_price": 1,
        "converted_fee": 2,
        "converted_currencyid": "2003",
        "converted_steam_fee": 1,
        "converted_publisher_fee": 1,
        "converted_price_per_unit": 1,
        "converted_fee_per_unit": 2,
        "converted_steam_fee_per_unit": 1,
        "converted_publisher_fee_per_unit": 1,
        "asset": {
            "currency": 0,
            "appid": 730,
            "contextid": "2",
            "id": "6542776191",
            "amount": "1"
        }
    },
    "194035710805671301": {
        "listingid": "194035710805671301",
        "price": 0,
        "fee": 0,
        "publisher_fee_app": 730,
        "publisher_fee_percent": "0.10000000149011612",
        "currencyid": "2001",
        "asset": {
            "currency": 0,
            "appid": 730,
            "contextid": "2",
            "id": "6825071309",
            "amount": "0"
        }

    },

  }//end listinginfo
 //more fields here..
}

我需要从"listinginfo"节点中获取信息并将它们添加到一个dictionary<string, NewListedItem>中,其中字符串可以是例如:"637640274112277168",列表的类型为"NewListedItem",包含来自该子节点的所有信息。我的类看起来像这样:

class listinginfo
{
    public Dictionary<string, NewListedItem> Items;

}
class Asset
{
    public string currency { get; set; }
    public string appid { get; set; }
    public string contextid { get; set; }
    public string id { get; set; }
    public string amount { get; set; }
}
class NewListedItem
{

    public string listingid { get; set; }
    public string price { get; set; }
    public string fee { get; set; }
    public string publisher_fee_app { get; set; }
    public string publisher_fee_percent { get; set; }
    public string steam_fee { get; set; }
    public string publisher_fee { get; set; }
    public string converted_price { get; set; }
    public string converted_fee { get; set; }
    public string converted_currencyid { get; set; }
    public string converted_steam_fee { get; set; }
    public string converted_publisher_fee { get; set; }
    public string converted_fee_per_unit { get; set; }
    public string converted_steam_fee_per_unit { get; set; }
    public string converted_publisher_fee_per_unit { get; set; }
    public Asset asset { get; set; }


}

我该如何实现这一目标?

如果你愿意使用第三方库JSon.Net,这将会更容易。请参考这个相关的问题... https://dev59.com/-2Uo5IYBdhLWcg3wvRpF - dazedandconfused
@dazedandconfused既然问题被标记为[tag:json.net],我认为这应该没问题... - Marc Gravell
2
@MarcGravell - 哎呀,是这样的。在咖啡开始发挥作用之前,我不再评论了。 - dazedandconfused
3个回答

1
我无法以简洁的方式完成这项任务,但我相信这就是您要找的内容。
 var jsonString = @"{
            'success': true,
            'more': false,
            'results_html': 'a lot of html in here',
            'listinginfo': {
                '637640274112277168': {
                    'listingid': '637640274112277168',
                    'price': 50,
                    'fee': 7,
                    'publisher_fee_app': 730,
                    'publisher_fee_percent': '0.10000000149011612',
                    'currencyid': '2005',
                    'steam_fee': 2,
                    'publisher_fee': 5,
                    'converted_price': 1,
                    'converted_fee': 2,
                    'converted_currencyid': '2003',
                    'converted_steam_fee': 1,
                    'converted_publisher_fee': 1,
                    'converted_price_per_unit': 1,
                    'converted_fee_per_unit': 2,
                    'converted_steam_fee_per_unit': 1,
                    'converted_publisher_fee_per_unit': 1,
                    'asset': {
                                        'currency': 0,
                        'appid': 730,
                        'contextid': '2',
                        'id': '6542776191',
                        'amount': '1'
                    }
                },
                '194035710805671301': {
                    'listingid': '194035710805671301',
                    'price': 0,
                    'fee': 0,
                    'publisher_fee_app': 730,
                    'publisher_fee_percent': '0.10000000149011612',
                    'currencyid': '2001',
                    'asset': {
                            'currency': 0,
                            'appid': 730,
                            'contextid': '2',
                            'id': '6825071309',
                            'amount': '0'
                        }

                },
                }
        }";
        var json = JObject.Parse(jsonString);

        List<JToken> results = json["listinginfo"].Children().Children().ToList();
        var dictionaryResults = new ListingInfo();

        foreach (var token in results)
        {
            var info = JsonConvert.DeserializeObject<NewListedItem>(token.ToString());

            List<NewListedItem> listInfo = new List<NewListedItem>();
            listInfo.Add(info);

            dictionaryResults.Items = new Dictionary<string, List<NewListedItem>>();
            dictionaryResults.Items.Add(info.Listingid, listInfo);
        }

我还稍微修改了你类的属性名:

 public class Asset
    {
        public string Currency { get; set; }
        public string Appid { get; set; }
        public string Contextid { get; set; }
        public string Id { get; set; }
        public string Amount { get; set; }
    }
    public class NewListedItem
    {

        public string Listingid { get; set; }
        public string Price { get; set; }
        public string Fee { get; set; }
        [JsonProperty("publisher_fee_app")]
        public string PublisherFeeApp { get; set; }
        [JsonProperty("publisher_fee_percent")]
        public string PublisherFeePercent { get; set; }
        [JsonProperty("steam_fee")]
        public string SteamFee { get; set; }
        [JsonProperty("publisher_fee")]
        public string PublisherFee { get; set; }
        [JsonProperty("converted_price")]
        public string ConvertedPrice { get; set; }
        [JsonProperty("converted_fee")]
        public string ConvertedFee { get; set; }
        [JsonProperty("converted_currencyid")]
        public string ConvertedCurrencyid { get; set; }
        [JsonProperty("converted_steam_fee")]
        public string ConvertedSteamFee { get; set; }
        [JsonProperty("converted_publisher_fee")]
        public string ConvertedPublisherFee { get; set; }
        [JsonProperty("converted_fee_per_unit")]
        public string ConvertedFeePerUnit { get; set; }
        [JsonProperty("converted_steam_fee_per_unit")]
        public string ConvertedSteamFeePerUnit { get; set; }
        [JsonProperty("converted_publisher_fee_per_unit")]
        public string ConvertedPublisherFeePerUnit { get; set; }
        public Asset Asset { get; set; }


    }

1
你真的非常接近成功了。你定义的类应该可以正常工作,除了需要将根类中的字典属性名称从Items更改为listinginfo以反映JSON属性名称。(或者,你可以使用[JsonProperty]属性将Items字典映射到JSON中的listinginfo属性)。在进行这些更改后,我建议你将根类从listinginfo重命名为其他有意义的名称,比如ListingResponse,但这不是必须的。
进行这些更改后,你的根类应该如下所示:
public class ListingResponse
{
    public Dictionary<string, NewListedItem> listinginfo { get; set; }
}

或者,如果您更喜欢属性方法:

public class ListingResponse
{
    [JsonProperty("listinginfo")]
    public Dictionary<string, NewListedItem> Items { get; set; }
}

然后,您应该能够将JSON反序列化为此类,并且您的字典将按您的预期填充:
ListingResponse response = JsonConvert.DeserializeObject<ListingResponse>(json);

Fiddle: https://dotnetfiddle.net/V8LsXY


(这是一段关于编程的内容,包含一个名为“Fiddle”的链接,链接指向https://dotnetfiddle.net/V8LsXY,保留了HTML格式。)

啊,我是这样解决的: JToken根= JObject.Parse(响应); JToken testToken = root [“listinginfo”]; 然后将testToken传递给DeserializeObject。不管怎样,谢谢! - ddacot

0
            public class TestClass
            {

                private void Test()
                {
                    var json = "{\r\n    \"637640274112277168\": {\r\n        \"listingid\": \"637640274112277168\",\r\n        \"price\": 50,\r\n        \"fee\": 7,\r\n        \"publisher_fee_app\": 730,\r\n        \"publisher_fee_percent\": \"0.10000000149011612\",\r\n        \"currencyid\": \"2005\",\r\n        \"steam_fee\": 2,\r\n        \"publisher_fee\": 5,\r\n        \"converted_price\": 1,\r\n        \"converted_fee\": 2,\r\n        \"converted_currencyid\": \"2003\",\r\n        \"converted_steam_fee\": 1,\r\n        \"converted_publisher_fee\": 1,\r\n        \"converted_price_per_unit\": 1,\r\n        \"converted_fee_per_unit\": 2,\r\n        \"converted_steam_fee_per_unit\": 1,\r\n        \"converted_publisher_fee_per_unit\": 1,\r\n        \"asset\": {\r\n            \"currency\": 0,\r\n            \"appid\": 730,\r\n            \"contextid\": \"2\",\r\n            \"id\": \"6542776191\",\r\n            \"amount\": \"1\"\r\n        }\r\n    },\r\n    \"194035710805671301\": {\r\n        \"listingid\": \"194035710805671301\",\r\n        \"price\": 0,\r\n        \"fee\": 0,\r\n        \"publisher_fee_app\": 730,\r\n        \"publisher_fee_percent\": \"0.10000000149011612\",\r\n        \"currencyid\": \"2001\",\r\n        \"asset\": {\r\n            \"currency\": 0,\r\n            \"appid\": 730,\r\n            \"contextid\": \"2\",\r\n            \"id\": \"6825071309\",\r\n            \"amount\": \"0\"\r\n        }\r\n    }\r\n    }\r\n\r\n";
                    Dictionary<string, NewListedItem> values = JsonConvert.DeserializeObject<Dictionary<string, NewListedItem>>(json);

                }
            }
            class listinginfo
            {
                public Dictionary<string, List<NewListedItem>> Items;

            }
            class Asset
            {
                public string currency { get; set; }
                public string appid { get; set; }
                public string contextid { get; set; }
                public string id { get; set; }
                public string amount { get; set; }
            }
            class NewListedItem
            {

                public string listingid { get; set; }
                public string price { get; set; }
                public string fee { get; set; }
                public string publisher_fee_app { get; set; }
                public string publisher_fee_percent { get; set; }
                public string steam_fee { get; set; }
                public string publisher_fee { get; set; }
                public string converted_price { get; set; }
                public string converted_fee { get; set; }
                public string converted_currencyid { get; set; }
                public string converted_steam_fee { get; set; }
                public string converted_publisher_fee { get; set; }
                public string converted_fee_per_unit { get; set; }
                public string converted_steam_fee_per_unit { get; set; }
                public string converted_publisher_fee_per_unit { get; set; }
                public Asset asset { get; set; }


            }

添加 Newtonsoft.Json 的引用; - Hitesh Thakor
安装包 Newtonsoft.Json - 版本 6.0.7 - Hitesh Thakor
你已经放弃了JSON响应的其余部分,现在它可以工作了。但是如果有整个响应并运行您的代码,会出现以下错误:将值“True”转换为类型“ steambot.NewListedItem”时出错。路径“success”,第1行,第15个位置。从JSON可以看出,它也解析了第一行。我的想法是,如何仅传递listinginfo节点以进行反序列化? - ddacot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接