我有以下格式的 JSON(来自 couchDB View )
{"rows":[
{"key":["2015-04-01","524","http://www.sampleurl.com/"],"value":1},
{"key":["2015-04-01","524","http://www.sampleurl2.com/"],"value":2},
{"key":["2015-04-01","524","http://www.sampleurl3.com"],"value":1}
]}
我需要创建一个“服务”以从 couchDB 获取这些数据并以高效的方式将其插入 SQL Server(用于生成报告……)。我的第一个赌注是将此 json 批量插入 SQL Server,如下所示:Bulk Insert from Generic List into SQL Server with minimum lines of code
问题是,如何将这个 JSON 映射到 C# 类中?
直到现在,这就是我所做的:
public class Row
{
public List<string> key { get; set; }
public int value { get; set; }
}
public class RootObject
{
public List<Row> rows { get; set; }
}
var example = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(jsontext);
这给了我一个“行”列表。每行都有一个键,每个键都是一个包含日期、网址和数字的数组。
我可以遍历“行”并自行创建对象,但这对我来说听起来不是很高效。此外,JSON 会很大,大约 5MB 左右。
我想要的结构是这样的:
public class Click
{
public DateTime Date { get; set; }
public string Code { get; set; }
public string Url { get; set; }
public int Count { get; set; }
}
如何提取“键”数组并将其映射到单独的属性中。这样,我就不需要 for 循环了。
有什么想法吗?
最佳答案
您可以创建自定义 JsonConverter
为此:
[JsonConverter(typeof(ClickConverter))]
public class Click
{
public DateTime Date { get; set; }
public string Code { get; set; }
public string Url { get; set; }
public int Count { get; set; }
}
public class ClickConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(Click).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var token = JToken.Load(reader);
if (token == null || token.Type == JTokenType.Null)
return null;
var click = (existingValue as Click ?? new Click());
var key = token["key"] as JArray;
if (key != null && key.Count > 0)
click.Date = (DateTime)key[0];
if (key != null && key.Count > 1)
click.Code = (string)key[1];
if (key != null && key.Count > 2)
click.Url = (string)key[2];
var value = token["value"];
if (value != null)
click.Count = (int)value;
return click;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
// Fill in with the opposite of the code above, if needed
var click = value as Click;
if (click == null)
writer.WriteNull();
else
serializer.Serialize(writer,
new
{
// Update the date string format as appropriate
// https://msdn.microsoft.com/en-us/library/8kb3ddd4%28v=vs.110%29.aspx
key = new string[] { click.Date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), click.Code.ToString(CultureInfo.InvariantCulture), click.Url },
value = click.Count
});
}
}
public class RootObject
{
public List<Click> rows { get; set; }
}
将转换器直接应用于类后,您可以像往常一样(反)序列化:
var jsontext = @"{""rows"":[
{""key"":[""2015-04-01"",""524"",""http://www.sampleurl.com/""],""value"":1},
{""key"":[""2015-04-01"",""524"",""http://www.sampleurl2.com/""],""value"":2},
{""key"":[""2015-04-01"",""524"",""http://www.sampleurl3.com""],""value"":1}
]}";
var rows = JsonConvert.DeserializeObject<RootObject>(jsontext);
Debug.WriteLine(JsonConvert.SerializeObject(rows, Formatting.Indented));
关于c# - 将JSON反序列化为c#类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30987615/