Есть ли способ составить объект анонимного типа из JSON, не зная заранее о структуре объекта? - PullRequest
1 голос
/ 06 января 2011

У меня есть строка JSON, и я хотел бы использовать для создания объекта. Я еще не знаю о структуре объекта или свойствах, поэтому я не могу кодировать структуру, используя анонимный тип. Я застрял в .NET 3.5 в этом проекте, поэтому у меня пока нет доступа к новым возможностям .Net 4.0. Моя цель - использовать преобразованный объект в шаблонизаторе, аналогичном WebForms, Spark или Razor, для заполнения элементов шаблона в документе значениями из модели.

Я пробовал JavaScriptSerializer, у которого есть метод DeserializeObject, но он выводит словарь ключ / значение вместо объекта, напоминающего объект JSON. Есть еще идеи?

Если это поможет, вот модульный тест, который выражает то, что я пытаюсь сделать:

    [TestClass]
    public class when_deserializing_json_to_an_object : given_a_json_serializer_context
    {
        private object _expectedSerializedObject;
        private string _jsonStringToDeserialize;
        private object _result;

        protected override void Context()
        {
            base.Context();

            _expectedSerializedObject = new
                                            {
                                                Test = "123"
                                            };

            _jsonStringToDeserialize = "{\"Test\":\"123\"}";
        }

        protected override void BecauseOf()
        {
            _result = ObjectConverter.Deserialize(_jsonStringToDeserialize);
        }

        [TestMethod]
        public void it_should_return_the_expected_object()
        {
            var modelType = _result.GetType();
            var modelProperties = modelType.GetProperties();
            var testProperty = modelProperties.SingleOrDefault(x => x.Name == "Test");

            testProperty.GetValue( _result, null ).ShouldEqual( "123" );            
        }
    }

public abstract class given_a_json_serializer_context : SpecificationBase
    {
        protected IObjectConverter ObjectConverter;
        private JavaScriptSerializer _javascriptSerializer;

        protected override void Context()
        {
            _javascriptSerializer = new JavaScriptSerializer();
            ObjectConverter = new JsonObjectConverter(_javascriptSerializer) as IObjectConverter;
        }
    }

(SpecificationBase - это класс, который наша команда использует, чтобы помочь нам со спецификациями стиля BDD в MSTest)

Пока что производственный код, созданный на основе приведенной выше спецификации, выглядит следующим образом:

public class JsonObjectConverter : IObjectConverter
{
    private readonly JavaScriptSerializer _javascriptSerializer;

    public JsonObjectConverter(JavaScriptSerializer javascriptSerializer)
    {
        _javascriptSerializer = javascriptSerializer;
    }

    public object Deserialize(string json)
    {
        return _javascriptSerializer.DeserializeObject(json);
    }
}

На данный момент ясно, что JavaScriptSerializer не собирается делать трюк, потому что он просто превращает JSON в словарь пары ключ / значение.

Ответы [ 2 ]

6 голосов
/ 06 января 2011

Вы не можете создать анонимный тип, подобный этому, но вы можете создать новый класс.

Анонимные типы являются только анонимными для вас.Компилятор генерирует фактический тип для всех анонимных типов, и во время выполнения существует реальный тип, связанный с анонимными типами.Эти типы не создаются во время выполнения.

Однако вы можете создать десериализатор, который использует Reflection.Emit или любую аналогичную (более мощную) библиотеку для создания нового класса во время выполнения, имеющего соответствующую структуруа затем создать экземпляр и заполнить этот класс.

0 голосов
/ 25 ноября 2012

Возможно, вам поможет Json.NET:

"Json.NET - это популярная высокопроизводительная среда JSON для .NET"

http://json.codeplex.com/

...