最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】C#中,Json字符串转字典,并获得对应的Dictionary的键值

JSON crifan 11080浏览 0评论

【问题】

之前已经折腾过程类似的C#中处理json的问题:

【未解决】C#中从Json.Net解析后的Json中获得某个列表类型的变量

【已解决】C#中使用fastJson解析json字符串出错:Could not find token at index 3

【已放弃】C#中实现将Json字符串转换为变量

【已解决】C#中解析Json字符串

但是貌似都没真正的,彻底的解决问题。

记得后来看到别处,好像有真正的解决方案。

此处,又遇到类似问题:

从url为:

http://www.amazon.com/Kindle-Fire-HD/dp/B0083PWAPW/ref=lp_1055398_1_2?ie=UTF8&qid=1369820725&sr=1-2

得到json字符串:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
[
{
  "type" : "video",
  "mediaObjectId" : "m1X6Z4SRW3DC3U",
  "richMediaObjectId" : "",
  "preplayImages" : {
  },
  "html5PreferPosterHeight" : false,
  "thumbnailImageUrls" : {
  }
}
,
{
  "type" : "video",
  "mediaObjectId" : "m25IN8SS7SF6O1",
  "richMediaObjectId" : "",
  "preplayImages" : {
  },
  "html5PreferPosterHeight" : false,
  "thumbnailImageUrls" : {
  }
}
,
{
  "type" : "video",
  "mediaObjectId" : "m1STLVYO0U0INQ",
  "richMediaObjectId" : "",
  "preplayImages" : {
  },
  "html5PreferPosterHeight" : false,
  "thumbnailImageUrls" : {
  }
}
,
{
  "type" : "video",
  "mediaObjectId" : "m3CHUVJSUUOBU4",
  "richMediaObjectId" : "",
  "preplayImages" : {
  },
  "html5PreferPosterHeight" : false,
  "thumbnailImageUrls" : {
  }
}
,
{
  "type" : "video",
  "mediaObjectId" : "m3IVTAT62XST8A",
  "richMediaObjectId" : "",
  "preplayImages" : {
  },
  "html5PreferPosterHeight" : false,
  "thumbnailImageUrls" : {
  }
}
]

现在希望能够在C#,找到彻底的解决方案,将其转换为对应的字典类型的变量,然后获得对应的dict["preplayImages"]["L"]的值,即对应的Large类型的图片地址。

其中,在处理json转dict时,希望不需要预先定义对应的dict的结构体。

【解决过程】

1.参考:

Is there an existing library to parse JSON to Dictionary<String,Object> in .net?

去试试JavaScriptSerializer

注:

刚看到的,这里:

C# Json数据反序列化为Dictionary并根据关键字获取指定值

也是用的JavaScriptSerializer

2.但是发现找不到JavaScriptSerializer。

然后搜了下,发现在:

JavaScriptSerializer Class

3. 然后添加了:

1
using System.Web.Script.Serialization;

结果找不到Script。

才发现,原来是.NET Framework 4.5,中才有此库的。

然后最低支持此库的版本是.NET Framework 3.5。

而当前项目是.NET Framework 2.0的。

4. 所以还需要先换一下版本。

所以先去添加对应的dll库:System.Web.Extensions

reference dotnet system web extensions

然后再用:

1
using System.Web.Script.Serialization;

就可以了。

5.然后暂时使用:

1
2
3
4
//2. json to dict
var json = new JavaScriptSerializer() { MaxJsonLength = int.MaxValue };
//var dict = (IDictionary<string, object>)json.DeserializeObject(kibMasJson);
Object[] dictList = (Object[])json.DeserializeObject(kibMasJson);

是可以的。

后续的处理,还是有点问题的。

等有空弄好了再说。

6.后来经过折腾:

【已解决】C#中,Dictionary转换出错:Additional information: Unable to cast object of type ‘System.Collections.Generic.Dictionary`2[System.String,System.Object]‘ to type ‘System.Collections.Generic.Dictionary`2[System.String,System.String]‘

就搞定了对应的json转dic,且后续可以获得对应的dict中的某个特定的值了。

此处,提示完整的这部分的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//[
//{
//  "type" : "video",
//  "mediaObjectId" : "mJRPXDWU3S51F",
//  "richMediaObjectId" : "",
//  "preplayImages" : {
//  },
//  "html5PreferPosterHeight" : false,
//  "thumbnailImageUrls" : {
//  }
//}
//,
//{
//  "type" : "video",
//  "mediaObjectId" : "m26TT75OS8GNBU",
//  "richMediaObjectId" : "",
//  "preplayImages" : {
//  },
//  "html5PreferPosterHeight" : false,
//  "thumbnailImageUrls" : {
//  }
//}
//,
//{
//  "type" : "image",
//  "imageUrls" : {
//    "rich": {
//        width: null,
//        height: null
//    }
//  },
//  "altText" : "Kindle Paperwhite e-reader",
//  "thumbnailImageUrls" : {
//  }
//}
//,
//{
//  "type" : "image",
//  "imageUrls" : {
//    "rich": {
//        width: null,
//        height: null
//    }
//  },
//  "altText" : "Kindle Paperwhite e-reader",
//  "thumbnailImageUrls" : {
//  }
//}
//,
//{
//  "type" : "image",
//  "imageUrls" : {
//    "rich": {
//        width: null,
//        height: null
//    }
//  },
//  "altText" : "Kindle Paperwhite 3G: thinner than a pencil",
//  "thumbnailImageUrls" : {
//  }
//}
//]
 
//1. get json string
string kibMasJson = "";
if (crl.extractSingleStr(@"window\.kibMAs\s*=\s*(\[.+?\])\s*;\s*window\.kibConfig\s*=", respHtml, out kibMasJson, RegexOptions.Singleline))
{
    //2. json to dict
    var json = new JavaScriptSerializer() { MaxJsonLength = int.MaxValue };
    //var dict = (IDictionary<string, object>)json.DeserializeObject(kibMasJson);
    Object[] dictList = (Object[])json.DeserializeObject(kibMasJson);
 
    //3. get ["preplayImages"]["L"]
    //foreach (Dictionary<string, Object> eachImgDict in dictList)
    for (int idx = 0; idx < dictList.Length; idx++)
    {
        Dictionary<string, Object> eachImgDict = (Dictionary<string, Object>)dictList[idx];
        Object imgUrlObj = null;
        if (eachImgDict.ContainsKey("preplayImages"))
        {
            eachImgDict.TryGetValue("preplayImages", out imgUrlObj);
        }
        else if (eachImgDict.ContainsKey("imageUrls"))
        {
            eachImgDict.TryGetValue("imageUrls", out imgUrlObj);
        }
 
        if (imgUrlObj != null)
        {
 
            //"rich": {
            //    width: null,
            //    height: null
            //}
 
            //Type curType = imgUrlObj.GetType();
            Dictionary<string, Object> imgUrlDict = (Dictionary<string, Object>)imgUrlObj;
            Object largeImgUrObj = "";
            if (imgUrlDict.TryGetValue("L", out largeImgUrObj))
            {
                imageUrlList[idx] = largeImgUrObj.ToString();
                gotImageUrlOk = true;
            }
            else
            {
                //something wrong
                //not get all pic, so false
                gotImageUrlOk = false;
            }
        }
        else
        {
            //something wrong
            gotImageUrlOk = false;
        }
    }
}

 

【总结】

1. 使用.NET Framework 3.5+,则才有JavaScriptSerializer,即可用其将json字符串转换为所需的dict了。

2.转为Dict后,一般还需要将等到的Object转换为对应的类型的值,然后后续才能方便的去得到对应的值。

比如此处为了得到

["preplayImages"]["L"]

需要先得到对应的:

Dictionary<string, Object> eachImgDict = (Dictionary<string, Object>)dictList[idx];

再去用

eachImgDict.TryGetValue("preplayImages", out imgUrlObj);

得到对应的Object,再去用:

Dictionary<string, Object> imgUrlDict = (Dictionary<string, Object>)imgUrlObj;

得到对应的包含了L的那个Object,再去用:

imgUrlDict.TryGetValue("L", out largeImgUrObj)

imageUrlList[idx] = largeImgUrObj.ToString();

才得到最终需要的值。

转载请注明:在路上 » 【已解决】C#中,Json字符串转字典,并获得对应的Dictionary的键值

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
82 queries in 0.317 seconds, using 22.22MB memory