Deserializing JSON to .NET object using Newtonsoft

2018-12-31 14:45发布

I know there are a few posts about Newtonsoft so hopefully this isn't exactly a repeat...I'm trying to convert JSON data returned by Kazaa's API into a nice object of some kind

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

That JsonConvert line is just the most recent one I was trying...I'm not quite getting it and was hoping to eliminate some footwork by asking you guys. I was originally trying to convert it into a Dictionary or something...and actually, I just need to snag a couple of values in there so judging by the documentation, maybe Newtonsoft's LINQ to JSON might be a better choice? Thoughts/Links?

Here is an example of the JSON return data:

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

I did some more reading and found Newtonsoft's LINQ to JSON is exactly what I wanted...using WebClient, Stream, StreamReader, and Newtonsoft...I can hit Kazaa for JSON data, extract a URL, download the file, and do it all in like seven lines of code! I love it.

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

This post gets so many hits I thought it might be helpful to include the "using" bits that are discussed in the comments.

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条回答
其实,你不懂
2楼-- · 2018-12-31 15:20

You can use the C# dynamic type to make things easier. This technique also makes re-factoring simpler as it does not rely on magic-strings.

JSON

The JSON string below is a simple response from an HTTP API call, and it defines two properties: Id and Name.

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

C#

Use JsonConvert.DeserializeObject<dynamic>() to deserialize this string into a dynamic type then simply access its properties in the usual way.

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

If you specify the type of the results variable as dynamic, instead of using the var keyword, then the property values will correctly deserialize, e.g. Id to an int and not a JValue (thanks to GFoley83 for the comment below).

Note: The NuGet link for the Newtonsoft assembly is http://nuget.org/packages/newtonsoft.json.

查看更多
余生请多指教
3楼-- · 2018-12-31 15:22

Deserialize and get the value (when the collection is dynamic):

// 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;
}
查看更多
旧人旧事旧时光
4楼-- · 2018-12-31 15:26

If, like me, you prefer to deal with strongly typed objects** go with:

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

This way you get to use intellisense and compile time type error checking.

You can easily create the required objects by copying your JSON into memory and pasting it as JSON objects (Visual Studio -> Edit -> Paste Special -> Paste JSON as Classes).

See here if you don't have that option in Visual Studio.

You will also need to make sure your JSON is valid. Add your own object at the start if it is just an array of objects. i.e. {"obj":[{},{},{}]}

** I know that dynamic makes things easier sometimes but I'm a bit ol'skool with this.

查看更多
其实,你不懂
5楼-- · 2018-12-31 15:28

Finally Get State Name From JSON

Thankyou!

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
查看更多
皆成旧梦
6楼-- · 2018-12-31 15:33

Fairly late to this party, but I came across this issue myself today at work. Here is how I solved the issue.

I was accessing a 3rd party API to retrieve a list of books. The object returned a massive JSON object containing roughly 20+ fields, of which I only needed the ID as a List string object. I used linq on the dynamic object to retrieve the specific field I needed and then inserted it into my List string object.

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());
}
查看更多
登录 后发表回答