JSON.net将复杂的JSON字符串反序列化为C#数组

时间:2013-12-23 04:24:44

标签: c# json json.net deserialization

我已经有一段时间了,而且我变得越来越困惑和沮丧。在下面的代码中,我试图反序列化为一组“观察”。我已经尝试了很多东西,我知道问题是我的模型,但我很难理解如何实现它。这是file

这是类结构。

    public class Features
    {
        public int history { get; set; }
    }

    public class Response
    {
        public string version { get; set; }
        public string termsofService { get; set; }
        public Features features { get; set; }
    }

    public class Date
    {
        public string pretty { get; set; }
        public string year { get; set; }
        public string mon { get; set; }
        public string mday { get; set; }
        public string hour { get; set; }
        public string min { get; set; }
        public string tzname { get; set; }
    }

    public class Utcdate
    {
        public string pretty { get; set; }
        public string year { get; set; }
        public string mon { get; set; }
        public string mday { get; set; }
        public string hour { get; set; }
        public string min { get; set; }
        public string tzname { get; set; }
    }

    public class Date2
    {
        public string pretty { get; set; }
        public string year { get; set; }
        public string mon { get; set; }
        public string mday { get; set; }
        public string hour { get; set; }
        public string min { get; set; }
        public string tzname { get; set; }
    }

    public class Utcdate2
    {
        public string pretty { get; set; }
        public string year { get; set; }
        public string mon { get; set; }
        public string mday { get; set; }
        public string hour { get; set; }
        public string min { get; set; }
        public string tzname { get; set; }
    }

    public class Observation
    {
        public Date2 date { get; set; }
        public Utcdate2 utcdate { get; set; }
        public string tempm { get; set; }
        public string tempi { get; set; }
        public string dewptm { get; set; }
        public string dewpti { get; set; }
        public string hum { get; set; }
        public string wspdm { get; set; }
        public string wspdi { get; set; }
        public string wgustm { get; set; }
        public string wgusti { get; set; }
        public string wdird { get; set; }
        public string wdire { get; set; }
        public string pressurem { get; set; }
        public string pressurei { get; set; }
        public string windchillm { get; set; }
        public string windchilli { get; set; }
        public string heatindexm { get; set; }
        public string heatindexi { get; set; }
        public string precip_ratem { get; set; }
        public string precip_ratei { get; set; }
        public string precip_totalm { get; set; }
        public string precip_totali { get; set; }
        public string solarradiation { get; set; }
        public string UV { get; set; }
        public string softwaretype { get; set; }
    }

    public class Date3
    {
        public string pretty { get; set; }
        public string year { get; set; }
        public string mon { get; set; }
        public string mday { get; set; }
        public string hour { get; set; }
        public string min { get; set; }
        public string tzname { get; set; }
    }

    public class Utcdate3
    {
        public string pretty { get; set; }
        public string year { get; set; }
        public string mon { get; set; }
        public string mday { get; set; }
        public string hour { get; set; }
        public string min { get; set; }
        public string tzname { get; set; }
    }

    public class Dailysummary
    {
        public Date3 date { get; set; }
        public Utcdate3 utcdate { get; set; }
        public string meantempm { get; set; }
        public string meantempi { get; set; }
        public string meandewptm { get; set; }
        public string meandewpti { get; set; }
        public string meanwindspdm { get; set; }
        public string meanwindspdi { get; set; }
        public string meanwdire { get; set; }
        public string meanwdird { get; set; }
        public string humidity { get; set; }
        public string maxtempm { get; set; }
        public string maxtempi { get; set; }
        public string mintempm { get; set; }
        public string mintempi { get; set; }
        public string maxhumidity { get; set; }
        public string minhumidity { get; set; }
        public string maxdewptm { get; set; }
        public string maxdewpti { get; set; }
        public string mindewptm { get; set; }
        public string mindewpti { get; set; }
        public string maxpressurem { get; set; }
        public string maxpressurei { get; set; }
        public string minpressurem { get; set; }
        public string minpressurei { get; set; }
        public string maxwspdm { get; set; }
        public string maxwspdi { get; set; }
        public string precipm { get; set; }
        public string precipi { get; set; }
    }

    public class History
    {
        public Date date { get; set; }
        public Utcdate utcdate { get; set; }
        public List<Observation> observations { get; set; }
        public List<Dailysummary> dailysummary { get; set; }
    }

    public class RootObject
    {
        public Response response { get; set; }
        public History history { get; set; }
    }

我得到一个Null异常,我知道这意味着某些内容格式不正确,但我对JSON.net还不熟悉

public static void Main (string[] args)
    {

        JObject JsonData = JObject.Parse (File.ReadAllText(@"jsontest.json"));

        JArray Observations = (JArray)JsonData["observations"];

        Console.WriteLine (Observations[1].hum);
    }

有关如何使其发挥作用的任何建议?谢谢你们。

3 个答案:

答案 0 :(得分:2)

您发布的JSON似乎没有完全格式化。当你发布它时,它可能会被破坏。

修复之后,你应该反序列化你的对象:

RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(yourJSON);

在大多数情况下,您无需直接使用JObjectJArray

在此之前,我建议您浏览C#类并合并重复项。仅仅因为它是生成的,并不意味着它是消费它的最佳方式。

顺便说一句 - 这是一个非常糟糕的传递日期的方法。我很惊讶WUnderground在其API中没有使用ISO8601格式的日期。无论如何,您可能需要考虑在某个时候编写自定义JsonConverter以将其转换为普通DateTime类型,或者从Noda Time项目中转换为ZonedDateTime。否则,它们在C#中可能很难使用。

修改

我为你清理了一下。好吧,无论如何。节日快乐。

public class HistoryResponseContainer
{
    public ResponseInfo response { get; set; }
    public HistoryInfo history { get; set; }
}

public class ResponseInfo
{
    public string version { get; set; }
    public string termsofService { get; set; }
    public Dictionary<string, int> features { get; set; }
}

public class HistoryInfo
{
    public WUDate date { get; set; }
    public WUDate utcdate { get; set; }
    public Observation[] observations { get; set; }
    public Dailysummary[] dailysummary { get; set; }
}

public class WUDate
{
    public string pretty { get; set; }
    public string year { get; set; }
    public string mon { get; set; }
    public string mday { get; set; }
    public string hour { get; set; }
    public string min { get; set; }
    public string tzname { get; set; }

    public DateTime Value
    {
        get
        {
            int year = int.Parse(this.year);
            int month = int.Parse(this.mon);
            int day = int.Parse(this.mday);
            int hour = int.Parse(this.hour);
            int minute = int.Parse(this.min);

            var kind = this.tzname == "UTC"
                ? DateTimeKind.Utc
                : DateTimeKind.Unspecified;

            return new DateTime(year, month, day, hour, minute, 0, kind);
        }
    }
}

public class Observation
{
    public WUDate date { get; set; }
    public WUDate utcdate { get; set; }
    public string tempm { get; set; }
    public string tempi { get; set; }
    public string dewptm { get; set; }
    public string dewpti { get; set; }
    public string hum { get; set; }
    public string wspdm { get; set; }
    public string wspdi { get; set; }
    public string wgustm { get; set; }
    public string wgusti { get; set; }
    public string wdird { get; set; }
    public string wdire { get; set; }
    public string vism { get; set; }
    public string visi { get; set; }
    public string pressurem { get; set; }
    public string pressurei { get; set; }
    public string windchillm { get; set; }
    public string windchilli { get; set; }
    public string heatindexm { get; set; }
    public string heatindexi { get; set; }
    public string precipm { get; set; }
    public string precipi { get; set; }
    public string conds { get; set; }
    public string icon { get; set; }
    public string fog { get; set; }
    public string rain { get; set; }
    public string snow { get; set; }
    public string hail { get; set; }
    public string thunder { get; set; }
    public string tornado { get; set; }
    public string metar { get; set; }
}

public class Dailysummary
{
    public WUDate date { get; set; }
    public string fog { get; set; }
    public string rain { get; set; }
    public string snow { get; set; }
    public string snowfallm { get; set; }
    public string snowfalli { get; set; }
    public string monthtodatesnowfallm { get; set; }
    public string monthtodatesnowfalli { get; set; }
    public string since1julsnowfallm { get; set; }
    public string since1julsnowfalli { get; set; }
    public string snowdepthm { get; set; }
    public string snowdepthi { get; set; }
    public string hail { get; set; }
    public string thunder { get; set; }
    public string tornado { get; set; }
    public string meantempm { get; set; }
    public string meantempi { get; set; }
    public string meandewptm { get; set; }
    public string meandewpti { get; set; }
    public string meanpressurem { get; set; }
    public string meanpressurei { get; set; }
    public string meanwindspdm { get; set; }
    public string meanwindspdi { get; set; }
    public string meanwdire { get; set; }
    public string meanwdird { get; set; }
    public string meanvism { get; set; }
    public string meanvisi { get; set; }
    public string humidity { get; set; }
    public string maxtempm { get; set; }
    public string maxtempi { get; set; }
    public string mintempm { get; set; }
    public string mintempi { get; set; }
    public string maxhumidity { get; set; }
    public string minhumidity { get; set; }
    public string maxdewptm { get; set; }
    public string maxdewpti { get; set; }
    public string mindewptm { get; set; }
    public string mindewpti { get; set; }
    public string maxpressurem { get; set; }
    public string maxpressurei { get; set; }
    public string minpressurem { get; set; }
    public string minpressurei { get; set; }
    public string maxwspdm { get; set; }
    public string maxwspdi { get; set; }
    public string minwspdm { get; set; }
    public string minwspdi { get; set; }
    public string maxvism { get; set; }
    public string maxvisi { get; set; }
    public string minvism { get; set; }
    public string minvisi { get; set; }
    public string gdegreedays { get; set; }
    public string heatingdegreedays { get; set; }
    public string coolingdegreedays { get; set; }
    public string precipm { get; set; }
    public string precipi { get; set; }
    public string precipsource { get; set; }
    public string heatingdegreedaysnormal { get; set; }
    public string monthtodateheatingdegreedays { get; set; }
    public string monthtodateheatingdegreedaysnormal { get; set; }
    public string since1sepheatingdegreedays { get; set; }
    public string since1sepheatingdegreedaysnormal { get; set; }
    public string since1julheatingdegreedays { get; set; }
    public string since1julheatingdegreedaysnormal { get; set; }
    public string coolingdegreedaysnormal { get; set; }
    public string monthtodatecoolingdegreedays { get; set; }
    public string monthtodatecoolingdegreedaysnormal { get; set; }
    public string since1sepcoolingdegreedays { get; set; }
    public string since1sepcoolingdegreedaysnormal { get; set; }
    public string since1jancoolingdegreedays { get; set; }
    public string since1jancoolingdegreedaysnormal { get; set; }
}

用法:

string json = File.ReadAllText("jsontest.json");

var container = JsonConvert.DeserializeObject<HistoryResponseContainer>(json);

foreach (var observation in container.history.observations)
{
    // whatever you want to do with each observation

    // I also gave you easier access to the date. not perfect, but better.
    DateTime date = observation.date.Value;
    DateTime utc = observation.utcdate.Value;
}

答案 1 :(得分:1)

似乎json文件的内容无效,可能会错过{ }

我已尝试过这个json内容,但它确实有用。

{"response": {
  "version": "0.1",
  "termsofService": "http://www.wunderground.com/weather/api/d/terms.html",
  "features": {
  "history": 1
 }
 },
 "history": {
  "date": {
   "pretty": "December 18, 2013",
   "year": "2013",
   "mon": "12",
   "mday": "18",
   "hour": "00",
   "min": "00",
   "tzname": "America/Denver"
  }
 }
}

答案 2 :(得分:0)

您可以在此处以编程方式创建课程:http://json2csharp.com/

JSON必须有效。