关于c#:使用Newtonsoft将JSON反序列化为.NET对象(或者LINQ to JSON可能?)

Deserializing JSON to .NET object using Newtonsoft (or LINQ to JSON maybe?)

我知道有一些关于newtonsoft的文章,所以希望这不是一个重复…我正在尝试将kazaa的api返回的json数据转换成某种很好的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
WebClient client = new WebClient();
Stream stream = client.OpenRead("http://api.kazaa.com/api/v1/search.json?q=muse&type=Album");
StreamReader reader = new StreamReader(stream);

List<string> list = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>>(reader.Read().ToString());

foreach (string item in list)
{
    Console.WriteLine(item);
}

//Console.WriteLine(reader.ReadLine());
stream.Close();

那个jsonconvert线只是我最近尝试的一条线……我不太明白,我希望通过问你们来消除一些步法。我最初是想把它转换成字典之类的东西……实际上,我只需要在其中获取一些值,所以根据文档判断,牛顿的linq-to-json可能是更好的选择?思想/链接?

下面是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
77
78
79
{
 "page": 1,
 "total_pages": 8,
 "total_entries": 74,
 "q":"muse",
 "albums": [
    {
     "name":"Muse",
     "permalink":"Muse",
     "cover_image_url":"http://image.kazaa.com/images/69/01672812 1569/Yaron_Herman_Trio/Muse/Yaron_Herman_Trio-Muse_1.jpg",
     "id": 93098,
     "artist_name":"Yaron Herman Trio"
    },
    {
     "name":"Muse",
     "permalink":"Muse",
     "cover_image_url":"htt p://image.kazaa.com/images/54/888880301154/Candy_Lo/Muse/Candy_Lo-Muse_1.jpg",
     "i d": 102702,
     "artist_name":"\u76e7\u5de7\u97f3"
    },
    {
     "name":"Absolution",
     "permalink":" Absolution",
     "cover_image_url":"http://image.kazaa.com/images/65/093624873365/Mus e/Absolution/Muse-Absolution_1.jpg",
     "id": 48896,
     "artist_name":"Muse"
    },
    {
     "name":"Ab solution",
     "permalink":"Absolution-2",
     "cover_image_url":"http://image.kazaa.com/i mages/20/825646911820/Muse/Absolution/Muse-Absolution_1.jpg",
     "id": 118573,
     "artist _name":"Muse"
    },
    {
     "name":"Black Holes And Revelations",
     "permalink":"Black-Holes-An d-Revelations",
     "cover_image_url":"http://image.kazaa.com/images/66/093624428466/ Muse/Black_Holes_And_Revelations/Muse-Black_Holes_And_Revelations_1.jpg",
     "id": 48813,
     "artist_name":"Muse"
    },
    {
     "name":"Black Holes And Revelations",
     "permalink":"Bla ck-Holes-And-Revelations-2",
     "cover_image_url":"http://image.kazaa.com/images/86/ 825646911486/Muse/Black_Holes_And_Revelations/Muse-Black_Holes_And_Revelations_1 .jpg",
     "id": 118543,
     "artist_name":"Muse"
    },
    {
     "name":"Origin Of Symmetry",
     "permalink":"Origin-Of-Symmetry",
     "cover_image_url":"http://image.kazaa.com/images/29/825646 912629/Muse/Origin_Of_Symmetry/Muse-Origin_Of_Symmetry_1.jpg",
     "id": 120491,
     "artis t_name":"Muse"
    },
    {
     "name":"Showbiz",
     "permalink":"Showbiz",
     "cover_image_url":"http: //image.kazaa.com/images/68/825646182268/Muse/Showbiz/Muse-Showbiz_1.jpg",
     "id": 60444,
     "artist_name":"Muse"
    },
    {
     "name":"Showbiz",
     "permalink":"Showbiz-2",
     "cover_imag e_url":"http://image.kazaa.com/images/50/825646912650/Muse/Showbiz/Muse-Showbiz_ 1.jpg",
     "id": 118545,
     "artist_name":"Muse"
    },
    {
     "name":"The Resistance",
     "permalink":"T he-Resistance",
     "cover_image_url":"http://image.kazaa.com/images/36/825646864836/ Muse/The_Resistance/Muse-The_Resistance_1.jpg",
     "id": 121171,
     "artist_name":"Muse"
    }
  ],
 "per_page": 10
}

我做了更多的阅读,发现牛顿的linq-to-json正是我想要的……使用webclient、stream、streamreader和newtonsoft……我可以点击kazaa获取JSON数据,提取一个URL,下载文件,然后像七行代码一样完成所有操作!我喜欢它。

1
2
3
4
5
6
7
8
9
WebClient client = new WebClient();
Stream stream = client.OpenRead("http://api.kazaa.com/api/v1/search.json?q=muse&type=Album");
StreamReader reader = new StreamReader(stream);

Newtonsoft.Json.Linq.JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());

// Instead of WriteLine, 2 or 3 lines of code here using WebClient to download the file
Console.WriteLine((string)jObject["albums"][0]["cover_image_url"]);
stream.Close();

这篇文章获得了如此多的点击率,我认为将评论中讨论的"使用"部分包括在内可能会有所帮助。

1
2
3
4
5
6
7
using(var client = new WebClient())
using(var stream = client.OpenRead("http://api.kazaa.com/api/v1/search.json?q=muse&type=Album"))
using (var reader = new StreamReader(stream))
{
    var jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());
    Console.WriteLine((string) jObject["albums"][0]["cover_image_url"]);
}


您可以使用c dynamic类型来简化操作。这种技术也使得重分解变得简单,因为它不依赖于魔术字符串。

杰森

下面的JSON字符串是来自HTTP API调用的简单响应,它定义了两个属性:IdName

1
{"Id": 1,"Name":"biofractal"}

C.*

使用JsonConvert.DeserializeObject()将此字符串反序列化为动态类型,然后以通常的方式简单地访问其属性。

1
2
3
dynamic results = JsonConvert.DeserializeObject<dynamic>(json);
var id = results.Id;
var name= results.Name;

如果将results变量的类型指定为dynamic,而不是使用var关键字,则属性值将正确反序列化,例如,Idint而不是JValue(感谢下面的注释gfoley83)。

注意:NewtonSoft组件的nuget链接是http://nuget.org/packages/newtonSoft.json。

软件包:您也可以使用nuget live安装程序添加软件包,打开项目后,只需浏览软件包,然后安装、卸载、更新,它将被添加到依赖项/nuget下的项目中。


如果您只需要从JSON对象中获取一些项目,我将使用json.net的linq to json JObject类。例如:

1
2
3
4
JToken token = JObject.Parse(stringFullOfJson);

int page = (int)token.SelectToken("page");
int totalPages = (int)token.SelectToken("total_pages");

我喜欢这种方法,因为您不需要完全反序列化JSON对象。这在API中非常有用,有时会因为缺少对象属性而让您吃惊,比如Twitter。

文档:用json.net对json进行序列化和反序列化,用json.net对linq-to-json进行序列化和反序列化


使用dynamic关键字,解析此类对象变得非常容易:

1
2
3
4
5
6
7
8
9
10
dynamic x = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString);
var page = x.page;
var total_pages = x.total_pages
var albums = x.albums;
foreach(var album in albums)
{
    var albumName = album.name;

    // Access album data;
}


如果我弄错了,请纠正我,但我相信前面的示例与最新版本的james newton的json.net库有些不同步。

1
2
3
var o = JObject.Parse(stringFullOfJson);
var page = (int)o["page"];
var totalPages = (int)o["total_pages"];


如果与我一样,您更喜欢处理强类型对象**,请执行以下操作:

1
MyObj obj =  JsonConvert.DeserializeObject<MyObj>(jsonString);

这样就可以使用IntelliSense和编译时类型错误检查。

通过将JSON复制到内存中并粘贴为JSON对象(Visual Studio->Edit->Paste Special->Paste JSON as Classes),可以轻松地创建所需的对象。

如果在Visual Studio中没有该选项,请参见此处。

您还需要确保您的JSON是有效的。如果您自己的对象只是一个对象数组,请在开始时添加它。即"obj":[,,,]

我知道动态有时会让事情变得更简单,但我对这个有点太在行了。


反序列化并获取值(当集合是动态的时):

1
2
3
4
5
6
7
8
9
10
11
12
13
// First serializing
dynamic collection = new { stud = stud_datatable }; // The stud_datable is the list or data table
string jsonString = JsonConvert.SerializeObject(collection);


// Second Deserializing
dynamic StudList = JsonConvert.DeserializeObject(jsonString);

var stud = StudList.stud;
foreach (var detail in stud)
{
    var Address = detail["stud_address"]; // Access Address data;
}


我喜欢这种方法:

1
2
3
4
using Newtonsoft.Json.Linq;
// jsonString is your JSON-formatted string
JObject jsonObj = JObject.Parse(jsonString);
Dictionary<string, object> dictObj = jsonObj.ToObject<Dictionary<string, object>>();

现在,您可以使用dictObj作为字典访问任何您想要的内容。如果希望将值作为字符串获取,也可以使用Dictionary

您可以使用相同的方法来强制转换为任何类型的.NET对象。


另外,如果您只是在寻找嵌套在JSON内容中的特定值,那么可以这样做:

1
yourJObject.GetValue("jsonObjectName").Value<string>("jsonPropertyName");

等等。

如果您不想承担将整个JSON转换为C对象的成本,这可能会有所帮助。


参加这个聚会相当晚,但我今天上班时也遇到了这个问题。我就是这样解决这个问题的。

我正在访问第三方API以检索图书列表。对象返回了一个包含大约20多个字段的大型JSON对象,其中我只需要将ID作为一个列表字符串对象。我在动态对象上使用LINQ来检索我需要的特定字段,然后将其插入到列表字符串对象中。

1
2
3
4
5
6
7
8
9
dynamic content = JsonConvert.DeserializeObject(requestContent);
var contentCodes = ((IEnumerable<dynamic>)content).Where(p => p._id != null).Select(p=>p._id).ToList();

List<string> codes = new List<string>();

foreach (var code in contentCodes)
{
    codes.Add(code?.ToString());
}

我为JSON编写了一个扩展类:

1
2
3
4
5
6
7
 public static class JsonExtentions
    {
        public static string SerializeToJson(this object SourceObject) { return Newtonsoft.Json.JsonConvert.SerializeObject(SourceObject); }


        public static T JsonToObject<T>(this string JsonString) { return (T)Newtonsoft.Json.JsonConvert.DeserializeObject<T>(JsonString); }
}

设计模式:

1
2
3
4
5
6
7
8
 public class Myobject
    {
        public Myobject(){}
        public string prop1 { get; set; }

        public static Myobject  GetObject(string JsonString){return  JsonExtentions.JsonToObject<Myobject>(JsonString);}
        public  string ToJson(string JsonString){return JsonExtentions.SerializeToJson(this);}
    }

用途:

1
2
3
   Myobject dd= Myobject.GetObject(jsonstring);

                 Console.WriteLine(dd.prop1);


最后从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
Imports System
Imports System.Text
Imports System.IO
Imports System.Net
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Imports System.collections.generic

Public Module Module1
    Public Sub Main()

         Dim url As String ="http://maps.google.com/maps/api/geocode/json&address=attur+salem&sensor=false"
            Dim request As WebRequest = WebRequest.Create(url)
        dim response As WebResponse = DirectCast(request.GetResponse(), HttpWebResponse)
        dim reader As New StreamReader(response.GetResponseStream(), Encoding.UTF8)
          Dim dataString As String = reader.ReadToEnd()

        Dim getResponse As JObject = JObject.Parse(dataString)

        Dim dictObj As Dictionary(Of String, Object) = getResponse.ToObject(Of Dictionary(Of String, Object))()
        'Get State Name
        Console.WriteLine(CStr(dictObj("results")(0)("address_components")(2)("long_name")))
    End Sub
End Module