Можно ли десериализовать json для анонимного типа в С#?

Я прочитал из БД длинный json. Я хочу только один атрибут этого json.

У меня есть два варианта: а. Создайте интерфейс для этого json и выполните десериализацию этого интерфейса.  (Является ли это излишним, поскольку мне нужен только один атрибут?) б. Найти нужную подстроку (regex?)

какой из них предпочтительнее?

update: я использую .net 3.5

Ответы

Ответ 1

Почему бы вам не deserialize с помощью JSON.NET "LINQ to JSON" (JObject и т.д.) и просто попросите значение вам нужно по имени?

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

JObject json = JObject.Parse(text);
JToken value = json["foo"]["bar"];

(Я считаю, что JSON.NET также поддерживает dynamic в .NET 4, но здесь нет особой необходимости использовать его.)

Ответ 2

Регулярное выражение должно быть абсолютно вне всякого обсуждения. Просто забудь об этом, как будто он никогда не существовал.

Создание и работа с сильными типами - это хорошо и, вероятно, так, как я должен идти.

Но если вы хотите, вы также можете использовать dynamic:

class Program
{
    static void Main()
    {
        var json = "{ 'foo': { 'bar': 'bar value', 'baz': [ 1, 2, 3 ] } }";
        var serializer = new JavaScriptSerializer();
        dynamic value = serializer.DeserializeObject(json);
        Console.WriteLine(value["foo"]["baz"][1]);
    }
}

печатает 2 на консоли.

Ответ 3

В .NET 4:

Вы можете сделать что-то вроде того, что хотите, за вычетом необходимости в регулярном выражении (и вы не должны использовать регулярное выражение для чего-то подобного!), используя функцию dynamic для С# 4.0, описанную здесь: http://www.drowningintechnicaldebt.com/ShawnWeisfeld/archive/2010/08/22/using-c-4.0-and-dynamic-to-parse-json.aspx

Единственный недостаток заключается в том, что вы не можете гарантировать, какая именно структура объекта.

Подъем состоит в том, что вместо доступа к элементам через yourDynamicObject['blah'] он больше утка-типа-ish yourDynamicObject.blah

В .NET 3.5:

Вы можете использовать Json.NET: http://json.codeplex.com/

Ответ 4

Поиск подстроки - опасная оптимизация.

Стоит ли оптимизировать процесс (по сравнению с десериализацией JSON) и безопасно делать такой поиск? Мы не можем ответить "да", потому что это в основном зависит от контекста. Но я чувствую, что говорю НЕТ, потому что он явно ищет проблемы: даже если он работает сейчас, он может сломаться в будущем, когда изменится структура или содержимое вашего объекта.

Ответ 5

Старый поток, но здесь идет еще один метод .NET 3.5: вы можете передать объект, возвращенный DeserializeObject, в словарь < String, Object > . Это то же самое решение, что и с использованием динамического ключевого слова .NET 4.0:

JavaScriptSerializer serializer = new JavaScriptSerializer();
Object obj = serializer.DeserializeObject("{ 'name': 'vinicius fonseca', 'age': 31 }");
Dictionary<String, Object> ret = (Dictionary<String, Object>)obj;
Console.WriteLine(ret["name"].GetType().Name); // Output: String
Console.WriteLine(ret["name"].ToString()); // Output: vinicius fonseca
Console.WriteLine(ret["age"].GetType().Name); // Output: Int32
Console.WriteLine(ret["age"].ToString()); // Output: 31

Надеюсь, что это поможет кому-то.

Привет

Ответ 6

Это зависит.

Вариант A более строгий, дисциплинированный и формальный. Тем не менее, опять же, как вы сказали, это может быть излишним. Насколько жир этот json? В долгосрочной перспективе вариант A оставляет потенциальную возможность для будущего использования более чем одного объекта.

Вариант B определенно более неформальный и прямой. Это определенно будет работать сегодня, но в будущем может потребоваться другое решение.

Таким образом, возможно, вы захотите обернуть весь процесс в методе, чтобы скрыть реализацию от вызывающего клиента. Верните свой пользовательский объект только с одним одиночным заселением. Затем, если в будущем возникнет необходимость, вы можете изменить метод, чтобы использовать десериализацию полного наклона.

Примечание. Я не думаю, что десериализация анонимного типа в С# 3.5 возможна.

Ответ 7

Вы можете сделать:

var result = JsonConvert.DeserializeAnonymousType(json, new { Foo="", Bar=""});

Это вернет динамический объект с указанными вами полями.