【问题标题】:c# get values from jsonc# 从json中获取值
【发布时间】:2017-12-12 11:55:11
【问题描述】:

我有一个 json 文本,我想获取作者姓名和描述标签的值。不需要其他字段,例如 url 和 urltoimage 等等。 当我运行以下代码时,不提供任何字符串值。我认为这里有一些错误。

{
  "status": "ok",
  "articles": [
  {
    "source": {
      "id": "techcrunch",
      "name": "TechCrunch"
    },
    "author": "Khaled \"Tito\" Hamze",
    "title": "Crunch Report",
    "description": "Your daily roundup of the biggest TechCrunch stories and startup news.",
    "url": "https://techcrunch.com/video/crunchreport/",
    "urlToImage": "https://tctechcrunch2011.files.wordpress.com/2015/03/tccrshowogo.jpg?w=500&h=200&crop=1",
    "publishedAt": "2017-12-11T20:20:09Z"
  },
  {
    "source": {
      "id": "techcrunch",
      "name": "TechCrunch"
    },
    "author": "Sarah Perez",
    "title": "Facebook is trying to make the Poke happen again",
    "description": "Facebook's \"Poke\" feature has never really gone away, but now the social network is giving it a more prominent placement - and is even considering expanding..",
    "url": "https://techcrunch.com/2017/12/11/facebook-is-trying-to-make-the-poke-happen-again/",
    "urlToImage": "https://tctechcrunch2011.files.wordpress.com/2017/12/facebook-poke-icon.jpg",
    "publishedAt": "2017-12-11T20:02:30Z"
  },
  {
    "source": {
      "id": "techcrunch",
      "name": "TechCrunch"
    },
    "author": "Sarah Perez",
    "title": "Amazon Alexa can now wake you up to music",
    "description": "This fall, Amazon made a play to become your new alarm clock with the introduction of a combination smart speaker and clock called the Echo Spot. Today, the..",
    "url": "https://techcrunch.com/2017/12/11/amazon-alexa-can-now-wake-you-up-to-music/",
    "urlToImage": "https://tctechcrunch2011.files.wordpress.com/2017/09/amazon-event-9270069.jpg",
    "publishedAt": "2017-12-11T17:22:30Z"
  },
  {
    "source": {
      "id": "techcrunch",
      "name": "TechCrunch"
    },
    "author": "Ingrid Lunden, Katie Roof",
    "title": "Apple confirms Shazam acquisition; Snap and Spotify also expressed interest",
    "description": "After we broke the story last week that Apple was acquiring London-based music and image recognition service Shazam, Apple confirmed the news today. It is..",
    "url": "https://techcrunch.com/2017/12/11/apple-shazam-deal/",
    "urlToImage": "https://tctechcrunch2011.files.wordpress.com/2017/12/shazam-app-icon-ios.jpg",
    "publishedAt": "2017-12-11T15:59:31Z"
  }
]}

如何获得这个?下面是我的代码,它根本不起作用

var data = (JObject)JsonConvert.DeserializeObject(myJSON);
string nameArticles= data["articles"].Value<string>();
MessageBox.Show(nameArticles);


   public class Source
   {
    public string id { get; set; }
    public string name { get; set; }
   }
   public class Article
   {
    public Source source { get; set; }
    public string author { get; set; }
    public string title { get; set; }
    public string description { get; set; }
    public string url { get; set; }
    public string urlToImage { get; set; }
    public DateTime publishedAt { get; set; }
   }

            Article art = new Article();

            art = JsonConvert.DeserializeObject<Article>(myJSON);

            MessageBox.Show(art.description.ToString());

以上代码返回对象未设置为实例错误!

【问题讨论】:

  • data["articles"] 可能是 JArray 而不是字符串。您需要遍历上述JArray 中的每个JObject,取出authordescription 值。
  • @phuzi 你能展示一些示例代码吗?
  • 在下面查看我的答案

标签: c# json json.net


【解决方案1】:

data["articles"] 可能是 JArray 而不是字符串。您需要遍历前面提到的JArray 中的每个JObject,提取作者和描述值

var data = (JObject)JsonConvert.DeserializeObject(myJSON);
var articles = data["articles"].Children();

foreach (var article in articles)
{
    var author = article["author"].Value<string>();
    var description = article["author"].Value<string>();

    Console.WriteLine($"Author: " + author + ", Description: " + description);
}

这应该可以帮助您开始您正在做的任何事情。

【讨论】:

  • 感谢这个解决方案,经过这么多的努力,找到了这个并且成功了。!
【解决方案2】:

如果不想创建包装类,可以试试下面的代码 sn-p,它使用了dynamic typedeserialize JSON into an object

var json = "Your JSON string";

dynamic stuff = JsonConvert.DeserializeObject(json);

string name = stuff.status;
var arr = stuff.articles;

foreach (var a in arr)
{
   var authorName = a.author;
}

【讨论】:

    【解决方案3】:

    假设您希望反序列化为具体类(根据您的问题中显示的第二种尝试方法),那么您需要一个包装类来保存整个对象,并对其进行反序列化。

    目前您正尝试将整个对象序列化为 Article,但只有该对象的 articles 数组中的单个对象才能匹配您的 Article 类中的结构。

    您试图在对象的错误级别执行操作,而且您忘记了 articles 是一个列表(数组)这一事实。

    类似这样的:

    public class JSONResponse
    {
        public string status { get; set; }
        public List<Article> articles { get; set; }
    }
    

    JSONResponse response = JsonConvert.DeserializeObject<JSONResponse>(myJSON);
    

    然后您可以使用普通循环遍历response.articles 列表并提取作者姓名和描述。

    【讨论】:

    • 虽然反序列化为具体类可能有好处,但LINQ to JSON 也完全有效。
    • @crashmstr 这当然是一个同样有效的选择。然而 OP 的代码似乎表明他们想在 o 类中反序列化,但正在努力正确地做到这一点,所以我的答案是使用相同的方法构建的。你认为答案有什么错误吗?
    • 他们有两个代码块,一个在顶部使用 LINQ to JSON,另一个试图反序列化到更远的类。所以对于他们真正想要的是什么是模棱两可的。我不认为您的答案是错误,但我认为更好的措辞是如果他们想反序列化为一个类,他们需要在顶部这样做与整个结构水平。
    • @crashmstr 我添加了一点说明
    • 我认为这些变化使这成为一个更好的答案。
    【解决方案4】:

    您的 Json 制作下面的一组类

    public class Source
    { 
      public string id { get; set; } 
      public string name{get;set;}
    }
    public class Article
    {
    public Source source { get; set; }
    public string author { get; set; }
    public string title { get; set; }
    public string description { get; set; }
    public string url { get; set; }
    public string urlToImage { get; set; }
    public DateTime publishedAt { get; set; }
    }
    
    public class RootObject
    {
    public string status { get; set; }
    public List<Article> articles { get; set; }
    }
    

    所以你通过以下方式反序列化这个..

    var data = JsonConvert.DeserializeObject<RootObject>(myJSON);
    nameArticles=data.articles.FirstOrDefault().description;
    MessageBox.Show(nameArticles);
    

    【讨论】:

    • 虽然反序列化为具体类可能有好处,但LINQ to JSON 也完全有效。
    【解决方案5】:

    示例 json 数据

    string jsonString = "{\"displayName\":\"Alex Wu\",\"signInNames\":[{\"type\":\"emailAddress\",\"value\":\"AlexW@example.com\"},{\"type\":\"emailAddress\",\"value\":\"AlexW2@example.com\"}]}";
    

    将 json 转换为 jObject 并使用名为 selectToken() 的内置方法获取值

    JObject jObject = JObject.Parse(jsonString);
            string displayName = (string)jObject.SelectToken("displayName");
            string type = (string)jObject.SelectToken("signInNames[0].type");
            string value = (string)jObject.SelectToken("signInNames[0].value");
            Console.WriteLine("{0}, {1}, {2}", displayName, type, value);
            JArray signInNames = (JArray)jObject.SelectToken("signInNames");
            foreach (JToken signInName in signInNames)
            {
                type = (string)signInName.SelectToken("type");
                value = (string)signInName.SelectToken("value");
                Console.WriteLine("{0}, {1}",  type, value);
            }
    

    谢谢

    【讨论】:

      【解决方案6】:

      请为您的 JSON 文件创建一个类并为所有标签添加属性 然后编写如下代码:

      public class exampleJson{
      public string author {get;set;}
      public string description {get;set;}
      .....
      
      }
      
      var data = JsonConvert.DeserializeObject<exampleJson>(myJSON);
      string authorName = data.author;
      string descriptions = data.description ;
      

      【讨论】:

      • 虽然反序列化为具体类可能有好处,但LINQ to JSON 也完全有效。
      【解决方案7】:

      使用Json.NET

      示例:

              String[] your_json_file = Directory.GetFiles("C:\your_folder", json_file_name.json", SearchOption.AllDirectories);
              foreach (string s in your_json_file)
              {
                  JObject JSON = JObject.Parse(File.ReadAllText(s));
                  string AutorName = (string)JSON["author"];
                  string Description = (string)JSON["description"];
              }
      

      【讨论】:

      • 1.他们正在使用 Json.Net 2。"author""description" 不是示例中所示的顶级属性
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-19
      • 2018-11-15
      • 2020-10-16
      • 1970-01-01
      相关资源
      最近更新 更多