首页 文章

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

提问于
浏览
287

我知道有一些关于Newtonsoft的帖子,所以希望这不是一个重复...我正在尝试将Kazaa的API返回的JSON数据转换为某种类型的好对象

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系列只是我最近尝试的一个......我不是很了解它并且希望通过问你们来消除一些步法 . 我原本试图将它转换成字典或其他东西......实际上,我只需要在那里获取一些值,因此根据文档判断,也许Newtonsoft的LINQ to JSON可能是更好的选择?思考/链接?

以下是JSON返回数据的示例:

{
  "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
}

我做了一些阅读,发现Newtonsoft的LINQ to JSON正是我想要的...使用WebClient,Stream,StreamReader和Newtonsoft ......我可以点击Kazaa获取JSON数据,提取URL,下载文件,然后进行操作全部像七行代码!我喜欢它 .

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();

这篇文章获得了如此多的点击量,我认为包含评论中讨论的“使用”位可能会有所帮助 .

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"]);
}

11 回答

  • 0

    如果你只需要从JSON对象中获取一些项目,我会使用Json.NET的LINQ to JSON JObject 类 . 例如:

    JToken token = JObject.Parse(stringFullOfJson);
    
    int page = (int)token.SelectToken("page");
    int totalPages = (int)token.SelectToken("total_pages");
    

    我喜欢这种方法,因为您不需要完全反序列化JSON对象 . 这对于派对来说非常方便,因为它有时会让您感到惊讶,因为它缺少对象属性,比如Twitter .

    文档:Serializing and Deserializing JSON with Json.NETLINQ to JSON with Json.NET

  • 1

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

    JSON

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

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

    C#

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

    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 .

  • 10

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

    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;
    }
    
  • 242

    如果我错了,请纠正我,但我相信前一个例子与最新版本的James Newton的Json.NET库略有不同步 .

    var o = JObject.Parse(stringFullOfJson);
    var page = (int)o["page"];
    var totalPages = (int)o["total_pages"];
    
  • 21

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

    // 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;
    }
    
  • 232

    此外,如果您只是寻找嵌套在JSON内容中的特定值,您可以执行以下操作:

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

    等等 .

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

  • 33

    如果像我一样,你更愿意处理强类型物品**请使用:

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

    这样你就可以使用intellisense和编译时间类型错误检查 .

    您可以通过将JSON复制到内存中并将其粘贴为JSON对象(Visual Studio - >编辑 - >选择性粘贴 - >将JSON粘贴为类)来轻松创建所需对象 .

    如果在Visual Studio中没有该选项,请参阅here .

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

    **我知道 dynamic 有时会让事情变得更容易,但我会这样做 .

  • 7

    我喜欢这种方法:

    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<string, string> .

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

  • 6

    我为json开了一个Extionclass:

    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); }
    }
    

    设计模式:

    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);}
        }
    

    用法:

    Myobject dd= Myobject.GetObject(jsonstring);
    
                     Console.WriteLine(dd.prop1);
    
  • 7

    最后从JSON获取状态名称

    谢谢!

    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
    
  • 0

    这次聚会相当晚,但我今天在工作中遇到了这个问题 . 这是我如何解决这个问题 .

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

    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());
    }
    

相关问题