在c#中使用动态键创建JSON

时间:2014-12-14 02:28:14

标签: c# json

我正在尝试复制以下JSON结构:

{"result_content": {
    "data": {
         "city_name" : "Beverly Hills",
         "2014-06-05T00:00:00": {
         "morning_low": "20",
         "daytime_high": "40"
         },
         "2014-06-06T00:00:00": {
         "morning_low": "21",
         "daytime_high": "41"
         },
         "2014-06-07T00:00:00": {
         "morning_low": "22",
         "daytime_high": "42"
         },
        "2014-06-08T00:00:00": {
        "morning_low": "23",
        "daytime_high": "43"
        },
        "2014-06-09T00:00:00": {
        "morning_low": "24",
        "daytime_high": "44"
        }
      }
    }
  }

但我无法弄清楚如何使用C#创建动态键。

这是我的对象类

public class Day
{
    public string morning_low { get; set; }
    public string daytime_high { get; set; }
}

public class Data
{
    public string city_name { get; set; }
    public List<Day> days { get; set; }
}

public class ResultContent
{
    public Data data { get; set; }
}

以下是我如何建立这一切:

            ResultContent content = new ResultContent();
            content.data = new Data();
            content.data.city_name = results.Body.GetCityForecastByZIPResponse.GetCityForecastByZIPResult.City;

            foreach (Forecast day in results.Body.GetCityForecastByZIPResponse.GetCityForecastByZIPResult.ForecastResult.Forecast){
                Day x = new Day();
                x.daytime_high = day.Temperatures.DaytimeHigh;
                x.morning_low = day.Temperatures.MorningLow;
                content.data.days.Add(x);
            }

            return JsonConvert.SerializeObject(content);

这只返回一个JSON数组,这不是我想要的。我在结果对象中有DateTime。

3 个答案:

答案 0 :(得分:1)

我认为这应该是一系列日子并以你所要求的方式表现出来,因为创建动态json格式很难解析。

他们定义它应该产生如下所示的东西。

{
    "result_content": {
        "data": {
             "city_name" : "Beverly Hills",
             "days" : 
             [
                 {
                     "morning_low": "20",
                     "daytime_high": "40"
                 },
                 {
                     "morning_low": "21",
                     "daytime_high": "41"
                 },
                 {
                     "morning_low": "22",
                     "daytime_high": "42"
                 },
                 {
                     "morning_low": "23",
                     "daytime_high": "43"
                 },
                 {
                     "morning_low": "24",
                     "daytime_high": "44"
                 }
            ]
        }
    }
}

您缺少的是当天本身,应在您的Day课程中定义。添加它以获取:

"days" : 
[
    {
        "day" : "2014-06-05T00:00:00",
        "morning_low": "20",
        "daytime_high": "40"
    }
    ...
]

答案 1 :(得分:1)

如果您真的想要这种复杂的格式,我会使用自定义JsonConverter

public class Day
{
    public string morning_low { get; set; }
    public string daytime_high { get; set; }
}

[JsonConverter(typeof(Data.Converter))]
public class Data
{
    public string city_name { get; set; }
    public Dictionary<DateTime, Day> days { get; set; }

    public class Converter : JsonConverter
    {
        public override bool CanConvert(Type type) { return type == typeof(Data); }
        public override object ReadJson(JsonReader reader, Type type, object value, JsonSerializer serializer) 
        {
            Data obj = new Data();
            obj.days = new Dictionary<DateTime, Day>();
            DateTime v;
            while (reader.Read() && reader.TokenType != JsonToken.EndObject)
            {
                if (reader.TokenType != JsonToken.PropertyName)
                    throw new JsonSerializationException("Unexpected token type");

                if ("city_name" == (string)reader.Value)
                {
                    if (obj.city_name != null)
                        throw new JsonSerializationException("Duplicate key: city_name");
                    obj.city_name = reader.ReadAsString();
                }
                else if (DateTime.TryParseExact((string)reader.Value, serializer.DateFormatString, 
                                                serializer.Culture, DateTimeStyles.None, out v))
                {
                    reader.Read();
                    obj.days.Add(v, serializer.Deserialize<Day>(reader));
                }
                else
                {
                    if (serializer.MissingMemberHandling == MissingMemberHandling.Error)
                        throw new JsonSerializationException("Unexpected property: " + reader.Value);
                    reader.Read();
                    serializer.Deserialize(reader, reader.ValueType);
                }
            }
            return obj;
        }
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            Data obj = (Data)value;
            writer.WriteStartObject();
            writer.WritePropertyName("city_name");
            writer.WriteValue(obj.city_name);
            foreach (var pair in obj.days)
            {
                writer.WritePropertyName(pair.Key.ToString(serializer.DateFormatString));
                serializer.Serialize(writer, pair.Value);
            }
            writer.WriteEndObject();
        }
    }
}

public class ResultContent
{
    public Data data { get; set; }
}

public class ResultContentRoot
{
    public ResultContent result_content { get; set; }
}

public static void Main()
{
    var data = new Data();
    data.city_name = "New York";
    data.days = new Dictionary<DateTime, Day>();
    data.days.Add(DateTime.Today, new Day() { morning_low = "24", daytime_high = "29" });

    var result_content = new ResultContent();
    result_content.data = data;

    var root = new ResultContentRoot();
    root.result_content = result_content;

    var s = JsonConvert.SerializeObject(root);
}

我认为这是混合字典和对象合约的唯一方法。

如果您只需要单向序列化,也可以使用dynamic。它需要更少的代码:

public class Day
{
    public string morning_low { get; set; }
    public string daytime_high { get; set; }
}

public class ResultContent
{
    public dynamic data { get; set; }
}

public class ResultContentRoot
{
    public ResultContent result_content { get; set; }
}

public static void Main()
{
    dynamic data = new ExpandoObject();
    data.city_name = "New York";
    IDictionary<string, object> days = (IDictionary<string, object>)data;
    days.Add(DateTime.Today.ToString("yyyy-MM-dd'T'HH:mm:ss"), new Day() { morning_low = "24", daytime_high = "29" });

    var result_content = new ResultContent();
    result_content.data = data;

    var root = new ResultContentRoot();
    root.result_content = result_content;

    var s = JsonConvert.SerializeObject(root);
}

但它非常接近丢弃所有强类型,只是用JObject构建响应。

答案 2 :(得分:0)

在这种情况下,这可能是您正在寻找的......

void Main()
{
    Result result = new Result 
    {
        Data = new Data 
        {
            WeatherData = new List<City> 
            {
                new City 
                {
                    Name = "London",
                    Temp = new Dictionary<DateTime, TemperatureRange> 
                    {
                        { 
                            DateTime.UtcNow, 
                            new TemperatureRange 
                            {
                                DayHigh = 0,
                                MorningLow = 50
                            }
                        }
                    }
                }
            }
        }       
    };

    JsonConvert.SerializeObject(result);
}

public class Result
{
    [JsonProperty("result_content")]
    public Data Data { get; set; }
}

public class Data 
{
    [JsonProperty("data")]
    public List<City> WeatherData { get; set; }
}

public class City
{
    [JsonProperty("city_name")]
    public string Name { get; set; }

    public Dictionary<DateTime, TemperatureRange>  Temp { get; set; }
}

public class TemperatureRange
{
    public int MorningLow { get; set; }
    public int DayHigh { get; set; }
}