Упростить код десериализации

235
06 апреля 2019, 07:50

Помогите упростить код. Наверно, это можно сделать через LINQ или как-то ещё

var json = 
{
     "obj":{"order":["q957","q479","q214"],
            "quests":{
                         "q214":{"width":10,"name":"Телефон","id":"q214","type":"free"},
                         "q479":{"width":15,"name":"Имя","type":"free","id":"q479"},
                         "q957":{"width":100,"name":"Город","id":"q957","type":"free"}
                    },
            "id":"a525",
            "param":{"system":0,"name":"Данные пользователя", "multi":0}},
     "request.id":"fake-EC06814E-E35B-11E8-B22D-F854389B935E",
     "duration":0.042354,
     "_ehid":"212432.23074209719.1541684457"
}
    class Quest
    {
        public string Id { get; set; }
        public string Name { get; set; }
    }

        private T GetDeserialized<T>(string source)
        {
            return JsonConvert.DeserializeObject<T>(source);
        }
                        foreach (var root in GetDeserialized<Dictionary<string, dynamic>>(json))
                        {
                            if (root.Key == "obj")
                            {
                                foreach (var obj in GetDeserialized<Dictionary<string, dynamic>>(root.Value.ToString()))
                                {
                                    if (obj.Key == "quests")
                                    {
                                        foreach (var quest in GetDeserialized<Dictionary<string, dynamic>>(obj.Value.ToString()))
                                        {
                                            string questJSON = quest.Value.ToString().Replace("\r\n", string.Empty);
                                            Quest questObj = GetDeserialized<Quest>(questJSON);
                                            forms.Add(new Form(questObj.Id, questObj.Name));
                                        }
                                    }
                                }
                            }
                        }
Answer 1

Для упрощения создания структуры сериализации/десериализации в JSON рекомендую использовать сервис: https://app.quicktype.io/

// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
//    using QuickType;
//
//    var welcome = Welcome.FromJson(jsonString);
namespace QuickType
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;
    using J = Newtonsoft.Json.JsonPropertyAttribute;
    using R = Newtonsoft.Json.Required;
    using N = Newtonsoft.Json.NullValueHandling;
    public partial class Welcome
    {
        [J("obj")]        public Obj Obj { get; set; }         
        [J("request.id")] public string RequestId { get; set; }
        [J("duration")]   public double Duration { get; set; } 
        [J("_ehid")]      public string Ehid { get; set; }     
    }
    public partial class Obj
    {
        [J("order")]  public List<string> Order { get; set; }              
        [J("quests")] public Dictionary<string, Quest> Quests { get; set; }
        [J("id")]     public string Id { get; set; }                       
        [J("param")]  public Param Param { get; set; }                     
    }
    public partial class Param
    {
        [J("system")] public long System { get; set; }
        [J("name")]   public string Name { get; set; }
        [J("multi")]  public long Multi { get; set; } 
    }
    public partial class Quest
    {
        [J("width")] public long Width { get; set; } 
        [J("name")]  public string Name { get; set; }
        [J("id")]    public string Id { get; set; }  
        [J("type")]  public string Type { get; set; }
    }
    public partial class Welcome
    {
        public static Welcome FromJson(string json) => JsonConvert.DeserializeObject<Welcome>(json, QuickType.Converter.Settings);
    }
    public static class Serialize
    {
        public static string ToJson(this Welcome self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
    }
    internal static class Converter
    {
        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
        {
            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
            DateParseHandling = DateParseHandling.None,
            Converters =
            {
                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
            },
        };
    }
}
Answer 2

Лично я в основном пользуюсь бинарной сериализацией т.к. банально более универсальная (ней можно сохранять любые обьекты, в т.ч. и картинки).

Не уверен подойдет ли тебе, но, все равно, лови :)

public static class Serializator
{
    public static void Serialize(string pathOrFileName, object objToSerialise)
    {
        using (Stream stream = File.Open(pathOrFileName, FileMode.Create))
        {
            BinaryFormatter bin = new BinaryFormatter();
            bin.Serialize(stream, objToSerialise);
        }
    }
    public static T Deserialize<T>(string pathOrFileName) 
    {
        T items;
        using (Stream stream = File.Open(pathOrFileName, FileMode.Open))
        {
            BinaryFormatter bin = new BinaryFormatter();
            items = (T) bin.Deserialize(stream);
        }
        return items;
    }
}

Если нужно сериализовать инстансы собственного класа делаем такую штуку:

[Serializable]
public class SomeItem
{}

ну и, собственно, сам пример использования:

List<SomeItem> itemsCollected;//list with some data
Serializator.Serialize("data.dat", itemsCollected);
var a = Serializator.Deserialize<List<SomeItem>>("data.dat");
READ ALSO
Архитектура авторизации в приложении

Архитектура авторизации в приложении

Мое приложение авторизовываться с помощью одного метода Authorize в сервисе wcfАргумент ы метода - логин, пароль, параметры машины пользователя...

163
Работа с SqlCommandBuilder

Работа с SqlCommandBuilder

У меня есть 2 таблицы, хочу добавить по строке в каждую и передать изменения в БДПользуюсь при этом SqlCommandBuilder

190
Не работает Environment.NewLine в Mono

Не работает Environment.NewLine в Mono

Наступил на граблиИспользую RichTextBox в приложение на WindowsForms, которое в дальнейшем запускаю на Ubuntu коммандой mono TestApp

173
Нахождение чисел на картинке

Нахождение чисел на картинке

Изображение на вход

155