【问题】
之前已经折腾过程类似的C#中处理json的问题:
【未解决】C#中从Json.Net解析后的Json中获得某个列表类型的变量
【已解决】C#中使用fastJson解析json字符串出错:Could not find token at index 3
但是貌似都没真正的,彻底的解决问题。
记得后来看到别处,好像有真正的解决方案。
此处,又遇到类似问题:
从url为:
http://www.amazon.com/Kindle-Fire-HD/dp/B0083PWAPW/ref=lp_1055398_1_2?ie=UTF8&qid=1369820725&sr=1-2
得到json字符串:
现在希望能够在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。
然后搜了下,发现在:
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
然后再用:
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.后来经过折腾:
就搞定了对应的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" : { // "L" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KC/KC-slate-01-lg._V401028090_.jpg", // "S" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KC/KC-slate-01-sm._V401028090_.jpg" // }, // "html5PreferPosterHeight" : false, // "thumbnailImageUrls" : { // "selected" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KC/KC-slate-01-tn._V401028090_.jpg" // } //} //, //{ // "type" : "video", // "mediaObjectId" : "m26TT75OS8GNBU", // "richMediaObjectId" : "", // "preplayImages" : { // "L" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KC/KC-slate-02-lg._V389678398_.jpg", // "S" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KC/KC-slate-02-sm._V402265591_.jpg" // }, // "html5PreferPosterHeight" : false, // "thumbnailImageUrls" : { // "selected" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KC/KC-slate-02-tn._V389377315_.jpg" // } //} //, //{ // "type" : "image", // "imageUrls" : { // "L" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KC/KC-slate-03-lg._V400694812_.jpg", // "S" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KC/KC-slate-03-sm._V400694812_.jpg", // "rich": { // width: null, // height: null // } // }, // "altText" : "Kindle Paperwhite e-reader", // "thumbnailImageUrls" : { // "default": "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KC/KC-slate-03-tn._V400694812_.jpg" // } //} //, //{ // "type" : "image", // "imageUrls" : { // "rich": { // width: null, // height: null // } // }, // "altText" : "Kindle Paperwhite e-reader", // "thumbnailImageUrls" : { // "default": "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KC/KC-slate-04-tn._V389394767_.jpg" // } //} //, //{ // "type" : "image", // "imageUrls" : { // "L" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KC/KC-slate-05-lg._V389396235_.jpg", // "rich": { // width: null, // height: null // } // }, // "altText" : "Kindle Paperwhite 3G: thinner than a pencil", // "thumbnailImageUrls" : { // "default": "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KC/KC-slate-05-tn._V389377336_.jpg" // } //} //] //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 ) { //"L" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KC/KC-slate-01-lg._V401028090_.jpg", //"S" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KC/KC-slate-01-sm._V401028090_.jpg" //"L" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KC/KC-slate-03-lg._V400694812_.jpg", //"S" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KC/KC-slate-03-sm._V400694812_.jpg", //"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)) { //[0] "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-01-lg._V395919237_.jpg" //[1] "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-02-lg._V389394532_.jpg" //[2] "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-03-lg._V389394535_.jpg" //[4] "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-05-lg._V389394532_.jpg" 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();
才得到最终需要的值。