2

我正在尝试编写 .net c# 代码来读取调用的结果campaignEmailStatsAIMAll()

这是我得到的 JSON 结果示例:

{
   "total":3,
   "data":{
      "some...@company.com":[
         {
            "action":"click",
            "timestamp":"2012-10-18 20:55:52",
            "url":"http:\/\/www.someurl.com?ct=t(First_Chimp_Test10_18_2012)",
            "ip":"66.66.666.666"
         },
         {
            "action":"open",
            "timestamp":"2012-10-18 20:55:52",
            "url":null,
            "ip":"66.66.666.666"
         }
      ],
      "anothe...@corporation.com":[
         {
            "action":"open",
            "timestamp":"2012-10-18 20:18:05",
            "url":null,
            "ip":"22.222.222.222"
         },
         {
            "action":"open",
            "timestamp":"2012-10-18 20:18:18",
            "url":null,
            "ip":"22.222.222.222"
         },
         {
            "action":"click",
            "timestamp":"2012-10-18 20:18:18",
            "url":"http:\/\/www.someurl.com?ct=t(First_Chimp_Test10_18_2012)",
            "ip":"22.222.222.222"
         },
         {
            "action":"click",
            "timestamp":"2012-10-18 20:21:57",
            "url":"http:\/\/www.someurl.com?ct=t(First_Chimp_Test10_18_2012)",
            "ip":"22.222.222.222"
         }
      ],
      "thir...@business.com":[

      ]
   }
}

我遇到的问题是如何定义 C# 对象来接受这个 JSON 字符串。电子邮件地址被视为 JSON 名称/值对的名称部分。我知道 .NET 有 3rd 方包装器,但我只想调用这个 API(可能还有其他几个)并且更愿意自己编写代码。我希望能够遍历对象以提取电子邮件地址,然后为每个对象提取操作/时间戳/url。

当我将这个 JSON 放到 json2sharp.com 的对象创建器中时,我得到了这个:

public class SomebodyCompanyCom {     
   public string action { get; set; }     
   public string timestamp { get; set; }     
   public string url { get; set; }     
   public string ip { get; set; } 
}

public class AnotherpersonCorporationCom {     
   public string action { get; set; }      
   public string timestamp { get; set; }     
   public string url { get; set; }     
   public string ip { get; set; } 
}

public class Data {     
   public List<SomebodyCompanyCom> __invalid_name__somebody@company.com { get; set; }     
   public List<AnotherpersonCorporationCom> __invalid_name__anotherperson@corporation.com { get; set; }     
   public List<object> __invalid_name__thirdguy@business.com { get; set; } 
}

public class RootObject {     
   public int total { get; set; }     
   public Data data { get; set; } 
}
4

1 回答 1

1

像这样的生成器只能做出最好的猜测。由于 JSON 通常是无模式的,因此您需要分析数据并找出对其建模的最佳方法。

在您的情况下,您有两种基本类型:

  1. 由 action、timestamp、url 和 ip 组成的单个条目
  2. 包含总数和数据的整体容器

一个合理的模型可能如下所示:

public class ItemInfo {     
   public string action { get; set; }     
   public string timestamp { get; set; }     
   public string url { get; set; }     
   public string ip { get; set; } 
}

public class ContainerType {
    public int total;
    public Dictionary<string, ItemInfo[]> data;
}

如果您使用像JSON.Net这样的不错的 JSON 库,则可以将 JSON 字符串反序列化为 ContatinerType 结构,如下所示:

string rawJsonString = MagicallyGetTheJsonFromAWebservice();
ContainerType container = JsonConvert.DeserializeObject<ContainerType>(rawJsonString);

可能需要进行一些调整才能使类型反序列化准确工作,但这是基本思想。

编辑:执行反序列化的示例控制台程序:

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

namespace ConsoleApplication1
{
    class Program
    {
        static string testData = @"{
   'total':3,
   'data':{
      'some...@company.com':[
         {
            'action':'click',
            'timestamp':'2012-10-18 20:55:52',
            'url':'http:\/\/www.someurl.com?ct=t(First_Chimp_Test10_18_2012)',
            'ip':'66.66.666.666'
         },
         {
            'action':'open',
            'timestamp':'2012-10-18 20:55:52',
            'url':null,
            'ip':'66.66.666.666'
         }
      ],
      'anothe...@corporation.com':[
         {
            'action':'open',
            'timestamp':'2012-10-18 20:18:05',
            'url':null,
            'ip':'22.222.222.222'
         },
         {
            'action':'open',
            'timestamp':'2012-10-18 20:18:18',
            'url':null,
            'ip':'22.222.222.222'
         },
         {
            'action':'click',
            'timestamp':'2012-10-18 20:18:18',
            'url':'http:\/\/www.someurl.com?ct=t(First_Chimp_Test10_18_2012)',
            'ip':'22.222.222.222'
         },
         {
            'action':'click',
            'timestamp':'2012-10-18 20:21:57',
            'url':'http:\/\/www.someurl.com?ct=t(First_Chimp_Test10_18_2012)',
            'ip':'22.222.222.222'
         }
      ],
      'thir...@business.com':[

      ]
   }
}";

        public class ItemInfo {     
           public string action { get; set; }     
           public string timestamp { get; set; }     
           public string url { get; set; }     
           public string ip { get; set; } 
        }

        public class ContainerType {
            public int total;
            public Dictionary<string, ItemInfo[]> data;
        }
        static void Main(string[] args)
        {
            ContainerType container = JsonConvert.DeserializeObject<ContainerType>(testData);
            if((container.total != 3)
                || (container.data.Count != 3)
                || (container.data["some...@company.com"][1].action != "open")
                || (container.data["anothe...@corporation.com"][2].url != "http://www.someurl.com?ct=t(First_Chimp_Test10_18_2012)"))
            {
                Console.WriteLine("Failed to deserialize");
            }
            else
            {
                Console.WriteLine("Successfully deserialized");
            }

            foreach (string email in container.data.Keys)
            {
                Console.WriteLine(email);
                for (int x = 0; x < container.data[email].Count(); x++)
                {
                    Console.WriteLine("\t" + x.ToString() + ":");
                    Console.WriteLine("\t\taction   : " + container.data[email][x].action);
                    Console.WriteLine("\t\ttimestamp: " + container.data[email][x].timestamp);
                    Console.WriteLine("\t\turl      : " + container.data[email][x].url);
                    Console.WriteLine("\t\tip       : " + container.data[email][x].ip);
                }
            }
        }
    }
}
于 2012-10-23T17:35:14.103 回答