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
杰森
下面的JSON字符串是来自HTTP API调用的简单响应,它定义了两个属性:
1 | {"Id": 1,"Name":"biofractal"} |
C.*
使用
1 2 3 | dynamic results = JsonConvert.DeserializeObject<dynamic>(json); var id = results.Id; var name= results.Name; |
如果将
注意:NewtonSoft组件的nuget链接是http://nuget.org/packages/newtonSoft.json。
软件包:您也可以使用nuget live安装程序添加软件包,打开项目后,只需浏览软件包,然后安装、卸载、更新,它将被添加到依赖项/nuget下的项目中。
如果您只需要从JSON对象中获取一些项目,我将使用json.net的linq to json
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进行序列化和反序列化
使用
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>>(); |
现在,您可以使用
您可以使用相同的方法来强制转换为任何类型的.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 |