2015-06-22 7 views
1

У меня есть JSON в следующем формате (с точки зрения CouchDB)десериализации JSON в C# класс

{"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#?

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); 

Это дает мне список "Строки". Каждая строка имеет ключ, и каждый ключ представляет собой массив, содержащий дату, Url и число.

Я мог бы прокручивать «строки» и создавать объекты самостоятельно, но этот звук не очень эффективен для меня. Кроме того, JSON будет большой, что-то вроде 5 МБ больше или меньше.

Структура, которую я хочу что-то вроде этого:

public class Click 
{ 
    public DateTime Date { get; set; } 
    public string Code { get; set; } 
    public string Url { get; set; } 
    public int Count { get; set; } 
} 

Как я могу извлечь «ключ» массив и отобразить его на отдельные свойства. Таким образом, мне не нужен цикл for.

Любые идеи?

+0

ты выполнил простой Google поиск на самом деле есть тонны рабочих примеров, введите в вашем браузере следующее: 'C# stackoverflow Deserializing JSON в класс C#, дайте нам знать результаты – MethodMan

+0

. Моя проблема не десериализация. Я уже сделал это, как я объяснил в своем вопросе. Моя проблема заключается в том, чтобы отобразить в определенной форме. – jpgrassi

+0

, если вы хотите создать класс, сгенерированный определенным образом. В чем разница, можете ли вы объяснить, почему он должен быть в определенном порядке .. как только вы создадите класс и создадите экземпляр объекта, к которому у вас есть доступ ко всем людям свойства .. возможно вам нужно объяснить это лучше – MethodMan

ответ

2

Вы можете создать собственный 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)); 
+0

Это именно то, что я хотел. Большое спасибо! – jpgrassi

2

Здесь вы находитесь.

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 

Очевидное преимущество этого метода является то, что имеет низкую нагрузку. Его также легко поддерживать. Это также означает, что вы, очевидно, можете предоставить XmlIgnoreAttribute о свойствах, которые имеют на них ScriptIgnoreAttribute, а также выдают и читают действительный Serialized XML.

Примечание: Я использовал System.Web.Script.Serialization.JavaScriptSerializer. Если JSON.NET не использует ScriptIgnoreAttribute, вам необходимо применить любой атрибут, который он использует. (Я никогда не использовал JSON.NET.)

Другое примечание: Я написал это против C#6.0 и .NET 4.6. Ваши результаты могут отличаться.

Смежные вопросы