330

我知道有一些关于 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"]);
}
4

12 回答 12

279

您可以使用 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关键字,则属性值将正确反序列化,例如Id,反序列化为 anint而不是 a JValue(感谢 Gfoley83 的以下评论)。

注意:Newtonsoft 程序集的 NuGet 链接是http://nuget.org/packages/newtonsoft.json

:您也可以使用 nuget 实时安装程序添加包,打开您的项目只需浏览包,然后安装它install, unistall, update,它只会添加到您的项目下的 Dependencies/NuGet

于 2012-05-23T10:30:29.530 回答
273

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

JToken token = JObject.Parse(stringFullOfJson);

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

我喜欢这种方法,因为您不需要完全反序列化 JSON 对象。这在 API 中派上用场,这些 API 有时会因缺少对象属性而让您感到惊讶,例如 Twitter。

文档:使用 Json.NET 序列化和反序列化 JSON 以及使用 Json.NETLINQ to JSON

于 2011-01-20T16:29:28.720 回答
45

使用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;
}
于 2014-08-28T06:54:55.833 回答
23

如果像我一样,您更喜欢处理强类型对象**,请使用:

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

这样您就可以使用智能感知和编译时类型错误检查。

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

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

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

** 我知道动态有时会让事情变得更容易,但我对此有点过分。

于 2017-07-14T05:54:52.833 回答
22

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

var o = JObject.Parse(stringFullOfJson);
var page = (int)o["page"];
var totalPages = (int)o["total_pages"];
于 2011-01-20T17:54:54.673 回答
12

松散类型的动态列表- 反序列化并读取值

// 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;
}
于 2015-11-04T05:45:07.050 回答
9

我喜欢这种方法:

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 对象。

于 2016-03-29T17:26:50.397 回答
7

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

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

依此类推。

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

于 2015-01-15T19:01:37.047 回答
2

我为 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);
于 2018-06-08T18:21:17.643 回答
1

参加这个聚会已经很晚了,但我今天在工作中遇到了这个问题。这是我解决问题的方法。

我正在访问第 3 方 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());
}
于 2018-07-12T21:38:53.820 回答
0

最后从 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
于 2018-06-03T07:59:44.950 回答
0

使用 JsonConvert.DeserializeObject() 函数反序列化

public class ApiValues
    {
        [JsonProperty("Address")]
        public string Address { get; set; }

        [JsonProperty("BaseUrl")]
        public string BaseUrl{ get; set; }
    }

var json = 
{ 
    "Address":"some-address",
    "BaseUrl":"some-url-value"
}


var values = JsonConvert.DeserializeObject<ApiValues>(json);

于 2020-07-31T19:48:05.207 回答