Страницы

Поиск по вопросам

воскресенье, 29 декабря 2019 г.

Десериализация многих разных JSON на C#

#c_sharp #json #сериализация


Есть около сотни (в будущем больше) JSON. Каждый JSON имеет свою структуру. Необходимо
их все десериализовать. Пытаюсь использовать стандартный класс DataContractJsonSerializer,
пользуюсь этой схемой.

При создании экземпляра класса нужно передавать ему тип сериализуемых или десериализуемых
экземпляров

DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person));


Как я уже сказал, у меня много разных типов, но метод, осуществляющий десериализацию,
один. У меня есть строковые параметры с именами классов, описывающих структуру JSON,
например: "Person", "Address" и прочее.

Как их подставить в конструктор DataContractJsonSerializer так, чтобы не писать сотню
кейсов? Возможно ли это стандартными методами?

Пробовал это, но не работает.

Как вообще такие задачи решаются в промышленной среде?

В интернете полно примеров с одним жестко заданным JSON, но про много разных нигде
не нашел. 
    


Ответы

Ответ 1



Если вам изначально известно, какой объект представлен в json'e, то вам достаточно воспользоваться Generic-методом для дессериализации: var myNewObject = JsonConvert.DeserializeObject(json);

Ответ 2



Вам стоит воспользоваться JSON.NET (вот так подключается к проекту). После этого, чтобы не выписывать тип, вы можете десериализовать в JObject: using Newtonsoft.Json; using Newtonsoft.Json.Linq; string json = "{\n" + " \"access_token\":\"13a85707de16fbb1c290250872f30e0b\",\n" + " \"error\":\n" + " { \"code\": \"0000\", \"text\": \"ok\" },\n" + " \"duration\": 0.025489807128906\n" + "}"; var o = JObject.Parse(json); Если вы знаете имя свойства, им можно легко воспользоваться: var accessToken = (string)o["access_token"]; // "13a85707de16fbb1c290250872f30e0b" var errorCode = (int)o["error"]["code"]; // 0 var duration = TimeSpan.FromSeconds((double)o["duration"]); // {00:00:00.0250000}

Ответ 3



Если приложению доступна сборка, в которой находится нужный класс, и у вас есть имя этого класса, вы можете загрузить assembly, найти в ней соответствующий тип, а затем передать его в конструктор DataContractJsonSerializer: using System; using System.Reflection; using System.Runtime.Serialization.Json; AssemblyName asn = new AssemblyName("Assembly.Name"); Assembly assembly = Assembly.Load(asn); Type tp = assembly.GetType("Person"); if (tp == null) throw new TypeAccessException(); var ser = new DataContractJsonSerializer(tp); object person = ser.ReadObject(stream); // => Person

Ответ 4



public static T FromJson(this string objString) { var stream = objString.GetMemoryStream(); stream.Position = 0; var ser = new DataContractJsonSerializer(typeof(T)); return (T)ser.ReadObject(stream); } public static string ToJson(this T obj) { var stream = new MemoryStream(); var ser = new DataContractJsonSerializer(typeof(T)); ser.WriteObject(stream, obj); stream.Position = 0; var sr = new StreamReader(stream); return sr.ReadToEnd(); } Одно НО: не работает с многомерными массивами.

Комментариев нет:

Отправить комментарий