【问题】
之前已经折腾过程类似的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字符串:
[ { "type" : "video", "mediaObjectId" : "m1X6Z4SRW3DC3U", "richMediaObjectId" : "", "preplayImages" : { "L" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-01-lg._V395919237_.jpg", "S" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-01-sm._V401027115_.jpg" }, "html5PreferPosterHeight" : false, "thumbnailImageUrls" : { "default" : "http://g-ecx.images-amazon.com/images/G/01/kindle/whitney/dp/KW-imv-qt-tn._V167698598_.gif", "selected" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-shme-tour-tn._V396577301_.jpg" } } , { "type" : "video", "mediaObjectId" : "m25IN8SS7SF6O1", "richMediaObjectId" : "", "preplayImages" : { "L" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-shme-apps-lg._V396577301_.jpg", "S" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-shme-apps-sm._V396577300_.jpg" }, "html5PreferPosterHeight" : false, "thumbnailImageUrls" : { "default" : "http://g-ecx.images-amazon.com/images/G/01/kindle/whitney/dp/KW-imv-qt-tn._V167698598_.gif", "selected" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-shme-apps-tn._V396577301_.jpg" } } , { "type" : "video", "mediaObjectId" : "m1STLVYO0U0INQ", "richMediaObjectId" : "", "preplayImages" : { "L" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-shme-web-lg._V396577300_.jpg", "S" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-shme-web-sm._V396577306_.jpg" }, "html5PreferPosterHeight" : false, "thumbnailImageUrls" : { "default" : "http://g-ecx.images-amazon.com/images/G/01/kindle/whitney/dp/KW-imv-qt-tn._V167698598_.gif", "selected" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-shme-web-tn._V396577306_.jpg" } } , { "type" : "video", "mediaObjectId" : "m3CHUVJSUUOBU4", "richMediaObjectId" : "", "preplayImages" : { "L" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-shme-hd-lg._V396577300_.jpg", "S" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-shme-hd-sm.jpg" }, "html5PreferPosterHeight" : false, "thumbnailImageUrls" : { "default" : "http://g-ecx.images-amazon.com/images/G/01/kindle/whitney/dp/KW-imv-qt-tn._V167698598_.gif", "selected" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-shme-hd-tn._V396577306_.jpg" } } , { "type" : "video", "mediaObjectId" : "m3IVTAT62XST8A", "richMediaObjectId" : "", "preplayImages" : { "L" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-shme-social-lg._V396577301_.jpg", "S" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-shme-social-sm.jpg" }, "html5PreferPosterHeight" : false, "thumbnailImageUrls" : { "default" : "http://g-ecx.images-amazon.com/images/G/01/kindle/whitney/dp/KW-imv-qt-tn._V167698598_.gif", "selected" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KT/KT-slate-shme-social-tn._V396577301_.jpg" } } ]
现在希望能够在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. 然后添加了:
using System.Web.Script.Serialization;
结果找不到Script。
才发现,原来是.NET Framework 4.5,中才有此库的。
然后最低支持此库的版本是.NET Framework 3.5。
而当前项目是.NET Framework 2.0的。
4. 所以还需要先换一下版本。
所以先去添加对应的dll库:System.Web.Extensions
然后再用:
using System.Web.Script.Serialization;
就可以了。
5.然后暂时使用:
//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中的某个特定的值了。
此处,提示完整的这部分的代码:
//[ //{ // "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" : { // "default" : "http://g-ecx.images-amazon.com/images/G/01/misc/untranslatable-image-id.jpg", // "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" : { // "default" : "http://g-ecx.images-amazon.com/images/G/01/misc/untranslatable-image-id.jpg", // "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": { // src: "http://g-ecx.images-amazon.com/images/G/01/misc/untranslatable-image-id.jpg", // 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" : { // "L" : "http://g-ecx.images-amazon.com/images/G/01//kindle/dp/2012/KC/KC-slate-04-lg.jpg", // "S" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KC/KC-slate-04-sm.jpg", // "rich": { // src: "http://g-ecx.images-amazon.com/images/G/01/misc/untranslatable-image-id.jpg", // 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", // "S" : "http://g-ecx.images-amazon.com/images/G/01/kindle/dp/2012/KC/KC-slate-05-sm.jpg", // "rich": { // src: "http://g-ecx.images-amazon.com/images/G/01/misc/untranslatable-image-id.jpg", // 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": { // src: "http://g-ecx.images-amazon.com/images/G/01/misc/untranslatable-image-id.jpg", // 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" //[3] "http://g-ecx.images-amazon.com/images/G/01//kindle/dp/2012/KT/KT-slate-04-lg.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();
才得到最终需要的值。