C# 在c中使用动态键创建JSON#
我正在尝试复制以下JSON结构:C# 在c中使用动态键创建JSON#,c#,json,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_
{"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; }
}
这只是返回一个JSON数组,它不是我想要的。我的results对象中有DateTime。我认为它应该是一个天数数组,用您要求的方式表示它并不好,因为创建动态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"
}
]
}
}
}
你缺少的是一天本身,这应该在你的天
课程中定义。添加它以获得:
"days" :
[
{
"day" : "2014-06-05T00:00:00",
"morning_low": "20",
"daytime_high": "40"
}
...
]
在这种情况下,这可能就是你想要的
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; }
}
void Main()
{
结果=新结果
{
数据=新数据
{
WeatherData=新列表
{
新城
{
Name=“伦敦”,
新字典
{
{
DateTime.UtcNow,
新温度计
{
DayHigh=0,
晨低=50
}
}
}
}
}
}
};
序列化对象(结果);
}
公开课成绩
{
[JsonProperty(“结果内容”)]
公共数据数据{get;set;}
}
公共类数据
{
[JsonProperty(“数据”)]
公共列表天气数据{get;set;}
}
公营城市
{
[JsonProperty(“城市名称”)]
公共字符串名称{get;set;}
公共字典Temp{get;set;}
}
公共类温度
{
public int MorningLow{get;set;}
public int DayHigh{get;set;}
}
如果你真的想要如此复杂的格式,我会选择一个定制的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);
}
但是很快就要放弃所有的强类型,只使用
JObject
s构建响应了。是否“2014-06-05T00:00:00”是一个有效的属性名称?这是一个日期时间stampI看看它是什么,这不是我的问题我认为它不是一个有效的属性名称。然而,我的老板希望我能准确地发布它,所以我只是在探索我的选择,看看是否有可能以一种干净的方式发布。首先,你发布的JSON是无效的。在这里测试它我完全同意,它更干净,更容易编码,还可以让你轻松地遍历它,并处理数据,但不幸的是,我的老板想要用另一种方式。我反驳了,但他没有听你说,我最终使用了第一个解决方案,但现在我遇到了另一个问题。如何反序列化这个。用ReadJson
实现更新的转换器代码,所以它现在支持反序列化。可能并不是所有可能的输入错误都被检查,但它适用于有效的json。
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);
}
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);
}