c# - 将JSON反序列化为c#类

标签 c# json couchdb

我有以下格式的 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/

相关文章:

c# - XML/C# : Read content if only if attribute is correct

python - 将 dict 字段转换为 **list** 以在 **enumarate** 中使用

mysql - 有没有办法用 django 项目运行 python 脚本?

database - Cloudant:此排序不存在索引,请尝试按排序字段建立索引

c# - 为什么使用 Fiddler 时 HttpWebRequest 对象的性能会提高?

c# - C#中的UDP组播发送(使用JoinMulticastGroup)

c# - 使用 sql 身份验证的 sql 连接字符串

javascript - 创建上一个/下一个 html 页面导航

node.js - 如何使用node.js在redis数据库中保存多个json对象

ubuntu - 在旧 Ubuntu 10.04 上升级 couchdb/erlang