簡體   English   中英

將JSON反序列化為c#類

[英]Deserializing JSON into c# class

我有以下格式的JSON(從ouchDB視圖)

{"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}
]}

我需要創建一個“服務”以從ouchDB中獲取此數據,並以一種有效的方式將其插入到SQL Server中(用於生成報告。)。 我的第一個選擇是將這個json批量插入SQL Server,如下所示: 使用最少的代碼行將泛型列表從泛型列表插入SQL Server

問題是,如何將該JSON映射到ac#類?

Ultil現在這就是我所做的:

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循環。

有任何想法嗎?

這個給你。

public class Row
{
    // Serialize/Deserialize the `key` into it's values.
    public List<string> key { get { return new List<string>() { Date.ToString("yyyy-MM-dd"), Code, Url }; } set { Date = DateTime.Parse(value[0]); Code = value[1]; Url = value[2]; } }
    // Serialize/Deserialize the `value` into `Count`.
    public int value { get { return Count; } set { Count = value; } }

    [ScriptIgnore]
    public DateTime Date { get; set; }
    [ScriptIgnore]
    public string Code { get; set; }
    [ScriptIgnore]
    public string Url { get; set; }
    [ScriptIgnore]
    public int Count { get; set; }

    public override string ToString()
    {
        return Date.ToString("yyyy-MM-dd") + ", " + Code + ", " + Url + ", " + Count;
    }
}

public class RootObject
{
    public List<Row> rows { get; set; }
}

public static void _Main(string[] args)
{
    string json = "{\"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 jss = new JavaScriptSerializer();
    var example = jss.Deserialize<RootObject>(json);

    foreach (Row r in example.rows)
    {
        Console.WriteLine(r.ToString());
    }
}

它應該是不言自明的。 如果您想讓我詳細介紹,請問。 但是,這確實要求元素始終保持一致的順序。

以上輸出:

2015-04-01, 524, http://www.sampleurl.com/, 1
2015-04-01, 524, http://www.sampleurl2.com/, 2
2015-04-01, 524, http://www.sampleurl3.com, 1

這種方法的明顯好處是開銷低。 維護也很容易。 這也意味着您顯然可以在ScriptIgnoreAttribute具有ScriptIgnoreAttribute的屬性上提供XmlIgnoreAttribute ,並且它還會生成和讀取有效的Serialized XML。

注意:我使用了System.Web.Script.Serialization.JavaScriptSerializer 如果JSON.NET不使用ScriptIgnoreAttribute ,那么您必須應用它使用的任何屬性。 (我從未使用過JSON.NET 。)

另一個注意事項:我是針對C#6.0.NET 4.6編寫的。 您的結果可能會有所不同。

您可以為此創建一個定制的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));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM