Разобрать блок JSON с динамическими переменными - PullRequest
2 голосов
/ 12 апреля 2011

Я извлекаю объект JSON из URL и анализирую его с помощью JSON.NET. Я был в состоянии разобрать блоки данных с определенными переменными просто отлично, но когда дело доходит до случайного сбора var: value - я застрял.

Пример (свободно напечатанный):

{"FNAME":"joe","LNAME":"doe",<br> "BodyType":{"height":180,"weight":"200","race":"white","hair":"black"},<br> "BELONGINGS":{"shirt":"black","Money":15,"randomThing":"anyvar"},<br> "Signs":{"tattoo":0,"scar":"forehead","glasses":"dorky"}<br> }

Я приведу это к

Class Person<br> {<br> public string FNAME;<br> public string LNAME;<br> public BodyType bodyType;<br> public ????? belongings;<br> public ????? signs;<br> }<br> Как мне обращаться с вещами и знаками, если я не могу предсказать их свойства?

Ответы [ 2 ]

8 голосов
/ 12 апреля 2011

Есть два способа обращения с ними без знания содержимого во время выполнения.

Первый способ - использовать JObject JSON.Net, который будет обрабатывать упомянутый вами случай, плюс иерархии.

Второй способ - использовать System.Dynamic ExpandoObject, который недавно поддерживается в последних выпусках JSON.Net. К сожалению, он не совсем обрабатывает иерархии, но JSON.Net использует JObject для поддержки их при обнаружении. Для ваших целей это может быть более простым.

Вот пример с приведенным вами фрагментом и определениями. Также обратите внимание, что ExpandoObject можно напрямую преобразовать в IDictionary<string, object>, тогда как JObject имеет явные методы доступа к свойствам.

Персона соответствует ExpandoObject, а JPerson соответствует JObject.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Dynamic;

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;

namespace YourFavoriteNamespace
{
    public class JPerson
    {
        public string FNAME;
        public string LNAME;
        public BodyType bodyType;
        public JObject belongings;
        public JObject signs;
    }

    public class Person
    {
        public string FNAME;
        public string LNAME;
        public BodyType bodyType;
        public ExpandoObject belongings;
        public ExpandoObject signs;
    }

    public class BodyType
    {
        public int height;
        public int weight;
        public string race;
        public string hair;
    }

    class Program
    {
        static void DumpDynamic(dynamic d)
        {
            IDictionary<string, object> dynMap = (IDictionary<string, object>)d;
            foreach (string key in dynMap.Keys)
            {
                Console.WriteLine("  {0}={1} (type {2})", key, dynMap[key], null == dynMap[key] ? "null" : dynMap[key].GetType().Name);
            }
        }

        static void DumpJProperties(JObject jo)
        {
            var props = jo.Properties();
            foreach (JProperty prop in props)
            {
                Console.WriteLine("  {0}={1} (type {2})", prop.Name, prop.Value, null == prop.Value ? "null" : prop.Value.GetType().Name);
            }
        }

        static void DumpPerson(Person p)
        {
            Console.WriteLine("Person");
            Console.WriteLine("  FNAME={0}", p.FNAME);
            Console.WriteLine("  LNAME={0}", p.LNAME);
            Console.WriteLine("Person.BodyType");
            Console.WriteLine("  height={0}", p.bodyType.height);
            Console.WriteLine("  weight={0}", p.bodyType.weight);
            Console.WriteLine("  race  ={0}", p.bodyType.race);
            Console.WriteLine("  hair  ={0}", p.bodyType.hair);
            Console.WriteLine("Person.belongings");
            DumpDynamic(p.belongings);
            Console.WriteLine("Person.signs");
            DumpDynamic(p.signs);
        }

        static void DumpJPerson(JPerson p)
        {
            Console.WriteLine("Person");
            Console.WriteLine("  FNAME={0}", p.FNAME);
            Console.WriteLine("  LNAME={0}", p.LNAME);
            Console.WriteLine("Person.BodyType");
            Console.WriteLine("  height={0}", p.bodyType.height);
            Console.WriteLine("  weight={0}", p.bodyType.weight);
            Console.WriteLine("  race  ={0}", p.bodyType.race);
            Console.WriteLine("  hair  ={0}", p.bodyType.hair);
            Console.WriteLine("Person.belongings");
            DumpJProperties(p.belongings);
            Console.WriteLine("Person.signs");
            DumpJProperties(p.signs);
        }

        static void DoSimplePerson()
        {
            string initJson = "{\"FNAME\":\"joe\",\"LNAME\":\"doe\",\"BodyType\":{\"height\":180,\"weight\":\"200\",\"race\":\"white\",\"hair\":\"black\"},\"BELONGINGS\":{\"shirt\":\"black\",\"Money\":15,\"randomThing\":\"anyvar\"},\"Signs\":{\"tattoo\":0,\"scar\":\"forehead\",\"glasses\":\"dorky\"}}";
            Person p = JsonConvert.DeserializeObject<Person>(initJson);
            DumpPerson(p);
            Console.ReadLine();
        }

        static void DoComplexPerson()
        {
            string initJson = "{\"FNAME\":\"joe\",\"LNAME\":\"doe\",\"BodyType\":{\"height\":180,\"weight\":\"200\",\"race\":\"white\",\"hair\":\"black\"},\"BELONGINGS\":{\"shirt\":\"black\",\"Money\":15,\"randomThing\":\"anyvar\"},\"Signs\":{\"tattoo\":0,\"scar\":\"forehead\",\"glasses\":[\"dorky\",\"hipster\"]}}";
            Person p = JsonConvert.DeserializeObject<Person>(initJson);
            DumpPerson(p);
            Console.ReadLine();
        }

        static void DoJPerson()
        {
            string initJson = "{\"FNAME\":\"joe\",\"LNAME\":\"doe\",\"BodyType\":{\"height\":180,\"weight\":\"200\",\"race\":\"white\",\"hair\":\"black\"},\"BELONGINGS\":{\"shirt\":\"black\",\"Money\":15,\"randomThing\":\"anyvar\"},\"Signs\":{\"tattoo\":0,\"scar\":\"forehead\",\"glasses\":\"dorky\"}}";
            JPerson p = JsonConvert.DeserializeObject<JPerson>(initJson);
            DumpJPerson(p);
            Console.ReadLine();
        }

        static void Main(string[] args)
        {
            DoSimplePerson();
            DoComplexPerson();
            DoJPerson();
        }
    }
}
1 голос
/ 12 апреля 2011

Ну, они обязательно являются объектами JSON, верно, а объекты JSON - это ассоциативные массивы, отображающие строки во что-то. Поэтому я представляю их как Dictionary<string, dynamic> - карту строк с чем-то.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...