【问题标题】:Converting JSON data into an object将 JSON 数据转换为对象
【发布时间】:2015-05-07 10:28:46
【问题描述】:

我对此很陌生。如果我犯了任何错误,请原谅我。

我有 JSON 格式的数据。我可以直接读取这些数据并在 C# 代码中使用它吗?

根据我在互联网上阅读的理解,我认为我必须将其转换为对象形式才能使用数据。我说的对吗?

如果是,那么我看到这个方法转换如下:

string data = JsonConvert.DeserializeObject<string>(getmyissue());

getmyissue 是返回具有 json 格式数据的字符串的函数。

这给了我一个例外的说法

“读取字符串时出错。意外的令牌。”

谁能指导我哪里出错了?

编辑

MyIssue.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Example
{
    public class MyIssue
    {
        public string name{get;set;}
        public string description { get; set; }
        public string created { get;set; }
        public string updated{get;set;}
        public string displayName { get; set; }

    }
}

Program.cs

MyIssue obj=null;
        try
        {             
            obj = JsonConvert.DeserializeObject<MyIssue>(manager.getmyissue());
        }
        catch(Exception e)
        {
            Console.WriteLine(e.Message);
        }

        Console.WriteLine("Name:  "+obj.name);

【问题讨论】:

  • Newtonsoft.Json 有很好的 serdes,你一定要试试。
  • How to parse json in C#? 的可能重复项
  • @soner ,你是 SO 的编辑 :-)
  • @RoyiNamir 我只是尽力而为。我强烈觉得我有对称性疾病或 Stack Overflow 的问题。你知道..这是一种病态:)
  • 感谢您编辑 Soner :) 我喜欢这个社区 :)

标签: c# json


【解决方案1】:

在 C#/.NET 程序中反序列化 Json 的最简单方法是使用出色的 NewtonSoft JSON 库。

有很多方法可以做到这一点,但我不得不承认 NS 库只是继续完成任务(不,我不是团队成员等,只是一个 Avid 用户 :-) )。

做你想做的事,例如,如果你有:

{'Name': 'A person', 'AllowAccess': true,'Areas': ['Sales','Admin']}

您将首先构建一个对象来表示它,如下所示:

public MyObject
{
  public string Name { get; set; }
  public bool AllowAccess { get; set; }
  public List<string> Areas { get; set; }
}

完成此操作后,只需执行以下操作即可:

string jsonString = "// Your json formated string data goes here";
MyObject myObject = JsonConvert.DeserializeObject<MyObject>(jsonString);

此时,您对象中的属性应该反映您发送给它的 JSON 数据中的属性。

您当然需要通过 NuGet 或手动将 NS JSON 库添加到您的项目中,这对您来说更容易,您需要了解的一切都在这里:

How to install JSON.NET using NuGet?

然而,NS JSON 真正的好处不是易于使用,而是它还可以进行动态反序列化。

如果您不知道在收到的 JSON 中会发生什么,因此不知道如何提前构造一个对象来保存结果,这会派上用场。

然而,与其重复其他人所说的,您可以在此堆栈溢出帖子中找到更多关于动态处理的信息:

Deserializing JSON using JSon.NET with dynamic data

更新

查看您的 JSON 数据,您的字段/属性比您尝试解析的要多得多,而且没有一个常用的库(据我所知)会挑选要复制的字段,您要么有一个对象可以代表它们全部,或者根本不代表它们,我认为后者是您面临的问题。

我有一个相当简洁的“JSON”插件用于 chrome,而不是当给定大量 JSON 数据时,它可以很好地为我格式化输出并使其易于阅读,它在定义对象时也有很大帮助,让您可以看到您的数据的完整嵌套结构,这里有一系列图像显示使用此插件格式化的 JSON 数据:

我不打算再粘贴图像了,但要再粘贴 4 页!!

现在,一些额外的信息可能会对您有所帮助。

根据经验(我必须为这些 Jira webhook 编写 PHP 解析器),我知道在 Jira 控制面板中,您可以将 webhook 配置为仅返回您感兴趣的信息。

现在,您似乎刚刚告诉系统转​​储所有内容,对于您也已上钩的每个事件(看起来 - 全部),我已经有一段时间没有对这些进行任何工作了,但除了全局 webhook 之外,您还拥有单独的 webhook,它们只触发特定事件并生成比您在此处处理的要小得多的 JSON 数据。

因此,我建议您查看您的 Jira 控制面板(或让您的 Admin/Lead Dev/etc 查看)并尽可能多地减少这些数据。

此外,如果我没记错的话,您还可以对 Jira 服务进行各种 Web API 调用以获取此信息,在这种情况下,您可以准确地告诉 API 您感兴趣的内容,这意味着它只会返回您需要的字段。

现在,您的主要问题是您尝试处理的数据量非常庞大,如果您解决了这个问题,您会发现围绕您尝试运行的代码的问题将更容易处理。

更新 2

为了更清楚地说明我使用“动态”类型获取数据的意思,您可以使用类似以下代码的内容:

string jsonString = "// Your json formated string data goes here";
var result = JsonConvert.DeserializeObject<dynamic>(jsonString);

这里的区别在于您使用的是 C# 动态类型,而不是您自己设计的强类型对象。

“动态”很有用,因为它有点像拥有一个空对象,然后为您添加属性,而无需您对其进行定义。

这实质上意味着,如果您传入以下 JSON:

{'Name': 'A person', 'AllowAccess': true,'Areas': ['Sales','Admin']}

你最终会得到一个看起来像这样的动态对象:

result = dynamic
{
  public string Name { get; set; }
  public bool AllowAccess { get; set; }
  public List<string> Areas { get; set; }
}

因此:

result.Name 

将让您访问名称字段的内容等等。

如果您的 JSON 被更改为:

{'Name': 'A person', 'AllowAccess': true,'Areas': ['Sales','Admin'], 'Location': 'The World' }

您的对象会神奇地拥有一个名为“Location”的属性,其中包含您可以使用的值“The World”来访问:

result.Location

在您的情况下,这将允许您定义具体对象 EG:

public MyObject
{
  public string Name { get; set; }
  public string Email { get; set; }
}

然后执行以下操作(假设您的入站 JSON 具有名为 Name & Email 的属性):

string jsonString = "// Your json formated string data goes here";
var result = JsonConvert.DeserializeObject<dynamic>(jsonString);
MyObject myObject = new MyObject
{
  Name = result.Name,
  Email = result.Email
}

然后您将丢弃不再需要的动态对象。

使用这种方法将遇到的问题是维护模型。手动属性分配对于少数属性和对象来说都很好,但随着软件的发展,它很快就会成为一个巨大的维护噩梦。

我敢肯定,如果您必须为 100 个不同的 JSON 请求和 50 种不同类型的对象执行此操作,您将面临什么样的任务。

因此,使用这种方法时,您应该考虑使用某种映射技术,例如“AutoMapper”,但是现在我建议您将其留到稍后再开始研究它,因为它会不能帮助您清楚地处理这种动态方法。

【讨论】:

  • 感谢您的回答。这是我尝试过的。但我的对象由于某种原因没有数据。我尝试在该行中放置一个断点,我注意到 myObject.Name 是null。知道错误发生在哪里吗?我已按照您的答案遵循了确切的方法。
  • 正确接收到json字符串。我已经通过在控制台上打印字符串来检查它。错误发生在转换为myObject时,
  • 更新您的问题并将您的项目中的确切代码复制/粘贴到上面的问题中,这可能是一个简单的错误,但除非我/我们可以阅读您的确切代码,否则我们真的不能帮助。为了完整起见,您还应该复制/粘贴打印在控制台上的确切 JSON 字符串,以便我们检查您的对象结构和 JSON 结构是否匹配。
  • 附加:还要确保 100% 确保您已将 newtonsoft JSON 添加到您的项目中,如果您没有添加,那么您将收到错误,因为无法找到该功能。
  • 那么您尝试解析 Jira WebHook 是吗? :-) 现在看。
【解决方案2】:

你得到的 JSON 已经是一个字符串,所以将它转换为字符串没有多大意义。您需要创建反映 JSON 字符串表示的结构的类。

例如,要将以下 JSON 转换为对象,您必须为用户创建一个类:

{"user":{"name":"asdf","teamname":"b","email":"c","players":["1","2"]}}

public class User
{
    public string name { get; set; }
    public string teamname { get; set; }
    public string email { get; set; }
    public Array players { get; set; }
}

那么你应该可以使用这个了:

JavaScriptSerializer jss= new JavaScriptSerializer(); 
List<User> users = jss.Deserialize<List<User>>(jsonResponse); 

【讨论】:

  • 是的,我的错。你是对的。我认为 DeseriiarizeObject 会将其转换为某种可读形式。我将尝试阅读有关如何创建反映 JSON 字符串表示的结构的类。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-28
  • 2010-12-13
  • 2021-11-18
  • 2017-05-04
  • 2017-06-16
  • 2012-07-21
相关资源
最近更新 更多