我正在尝试复制以下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。
答案 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; }
}