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

【问题】

之前已经折腾过程类似的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字符串:

[
{
  "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。

然后搜了下,发现在:

JavaScriptSerializer Class

3. 然后添加了:

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

然后再用:

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.后来经过折腾:

【已解决】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中的某个特定的值了。

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

//[
//{
//  "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();

才得到最终需要的值。



发表评论

电子邮件地址不会被公开。 必填项已用*标注

无觅相关文章插件,快速提升流量