【问题】
之前已经折腾过程类似的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();
才得到最终需要的值。