【问题标题】:How to make an c# object from json如何从 json 创建一个 c# 对象
【发布时间】:2013-08-29 15:01:04
【问题描述】:

我从网络服务中得到以下响应:

{
  "data":{
    "foo.hugo.info": {
      "path": "logon.cgi",
      "minVersion": 1,
      "maxVersion": 2
    },
    "foo.Fritz.Task": {
      "path": "Fritz/process.cgi",
      "minVersion": 1,
      "maxVersion": 1
    }
  },
  "success": true
}

json 对象必须如何反序列化?

或者还有其他方法可以获取属性的值吗?

【问题讨论】:

  • 你想反序列化它吗?
  • 将这些信息放入您的程序后,您想如何处理这些信息?虽然您可以将其反序列化为一个对象,但这可能是您可以避免的工作,具体取决于您的目标。
  • 您已经有一个 JSON 对象。您的意思是如何将其转换为 C# 对象?如果是这样,请创建一个具有 pathminVersionmaxVersion 属性的类,并使用 JSON.NET 之类的东西进行反序列化。
  • @Tragedian - 我想访问这些属性。像 data.foohugoinfo.path 这样的东西。但我只有这个字符串,不想解析这个。

标签: c# .net json


【解决方案1】:

使用 JSON.NET 库,这非常简单:

public class Root
{
    public Dictionary<string, Data> Data { get; set; }
    public bool Success { get; set; }
}

public class Data
{
    public string Path { get; set; }
    public int MinVersion { get; set; }
    public int MaxVersion { get; set; }
}

然后:

string json = 
@"{
  ""data"":{
    ""foo.hugo.info"": {
      ""path"": ""logon.cgi"",
      ""minVersion"": 1,
      ""maxVersion"": 2
    },
    ""foo.Fritz.Task"": {
      ""path"": ""Fritz/process.cgi"",
      ""minVersion"": 1,
      ""maxVersion"": 1
    }
  },
  ""success"": true
}";
Root root = JsonConvert.DeserializeObject<Root>(json);

在此示例中,我使用 Dictionary&lt;string, Data&gt; 对象对 2 个复杂键(foo.hugo.infofoo.Fritz.Task)进行建模,因为它们包含无法在 .NET 成员中使用的名称。

【讨论】:

  • 否决票的任何理由?请在投票时发表评论,解释为什么这个答案是错误的。
  • 这正是我所需要的!它还使用字典,可以处理两个以上的数据条目。谢谢!
【解决方案2】:

如果您使用的是 VS2012 或更高版本,您可以执行以下操作:

Edit > Paste Special > Paste JSON As Classes

用你的例子,结果是:

public class Rootobject
{
    public Data data { get; set; }
    public bool success { get; set; }
}

public class Data
{
    public FooHugoInfo foohugoinfo { get; set; }
    public FooFritzTask fooFritzTask { get; set; }
}

public class FooHugoInfo
{
    public string path { get; set; }
    public int minVersion { get; set; }
    public int maxVersion { get; set; }
}

public class FooFritzTask
{
    public string path { get; set; }
    public int minVersion { get; set; }
    public int maxVersion { get; set; }
}

【讨论】:

  • 关于您将使用什么序列化程序将 OP 中显示的 JSON 反序列化为这些类的任何代码示例?我对foohugoinfofooFritzTask 属性特别感兴趣。
  • 这可能无法完全回答 OP 的问题,但我不得不说...mind=blast。直到现在我才知道编辑菜单下隐藏着什么。
  • 这不灵活,如果添加第三个变体,您将需要创建另一个类并将其作为属性添加到Data 类中。
【解决方案3】:

查看此网站:http://json2csharp.com/

粘贴 json 字符串,它会为你生成类。我通常将它与 JSON.NET 结合使用来反序列化根对象的实例。

【讨论】:

  • 请仔细查看 JSON 并注意 foo.hugo.infofoo.Fritz.Task 键。现在看看你建议为Data 类生成的网站 - 非常没用。
  • 好点。我以前没有遇到过使用该网站的问题。 +1 为您提供更好的答案。
【解决方案4】:

您可以使用DataContractJsonSerializer

    [DataContract]
    public class DetailedData
    {
        [DataMember(Name="path")]
        public string Path { get; set; }
        [DataMember(Name = "minVersion")]
        public int MinVersion { get; set; }
        [DataMember(Name = "maxVersion")]
        public int MaxVersion { get; set; }
    }

    [DataContract]
    public class Data
    {
        [DataMember(Name = "foo.hugo.info")]
        public DetailedData Info { get; set; }
        [DataMember(Name = "foo.Fritz.Task")]
        public DetailedData Task { get; set; }
    }

    [DataContract]
    public class RootObject
    {
        [DataMember(Name = "data")]
        public Data Data { get; set; }
        [DataMember(Name = "success")]
        public bool Success { get; set; }
    }

    static void Main(string[] args)
    {
        string json = "...";
        DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(RootObject));

        RootObject obj = (RootObject)js.ReadObject(new MemoryStream(Encoding.Unicode.GetBytes(json)));
        Console.WriteLine(obj.Data.Task.MaxVersion); 
    }

编辑:InfoTask 的同一类

【讨论】:

  • 您可以为InfoTask 使用相同的类。除此之外,好的和完整的答案,+1。
  • 这很好用,但我忘了写的是 data: 是动态的。它可以是任意数量的不同项目,但每次都带有路径、minVersion 和 maxVersion 成员。只有名称(foo.hugo.info / foo.fritz.task)可以不同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-30
  • 2021-12-18
  • 2019-06-18
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多