Как сериализовать анонимный тип C# в строку JSON?

Я пытаюсь использовать следующий код для сериализации анонимного типа в JSON:

var serializer = new DataContractJsonSerializer(thing.GetType());
var ms = new MemoryStream();
serializer.WriteObject(ms, thing);
var json = Encoding.Default.GetString(ms.ToArray()); 

Однако при его выполнении возникает следующее исключение:

Type '<>f__AnonymousType1`3[System.Int32,System.Int32,System.Object[]]' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. See the Microsoft .NET Framework documentation for other supported types.

Я не могу применять атрибуты к анонимному типу (насколько мне известно). Есть ли другой способ сделать эту сериализацию или я что-то упустил?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
167
0
124 961
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

Ответ принят как подходящий

Попробуйте JavaScriptSerializer вместо DataContractJsonSerializer

JavaScriptSerializer serializer = new JavaScriptSerializer();
var output = serializer.Serialize(your_anon_object);

Но есть одна загвоздка. JavaScriptSerializer устарел.

Biswanath 28.03.2009 20:30

Trackback, похоже, устарел в SP1.

Biswanath 29.03.2009 00:34

для чего-то столь навязчивого, похоже, он используется во многих новых фреймворках Microsoft, включая MVC. aspnet.codeplex.com/SourceControl/changeset/view/21528#26649‌ 1

Nick Berardi 29.03.2009 05:13

Отлично подходит для отладки в тестовом проекте с фиктивными данными.

jpierson 29.12.2009 01:25

Как включить это в проект, отличный от asp.net (консольное приложение)?

Alxandr 27.07.2010 04:22

@Alxandr: Вам нужно будет сослаться на System.Web.Extensions.dll и добавить оператор using System.Web.Script.Serialization;.

randomguy 04.08.2010 21:38

Проблема @randomgui заключалась в том, что тип вывода проекта был установлен на профиль клиента.

Alxandr 05.08.2010 02:02

Как только это выполняется, вывод имеет тип string ... Как можно вернуть это как фактический объект json, скажем, в приложении MVC4, используя что-то вроде "return Json (output);"

longda 22.08.2013 23:27

Обратите внимание, что это с 2008 года. Сегодня я бы сказал, что сериализатор должен быть встроен и что вы, вероятно, можете использовать атрибуты swagger +, чтобы информировать потребителей о вашей конечной точке и возвращать данные.


Я бы поспорил, что вы не должен сериализовать анонимный тип. Я знаю искушение здесь; вы хотите быстро сгенерировать некоторые одноразовые типы, которые просто будут использоваться в среде с произвольным набором типов, известной как Javascript в браузере. Тем не менее, я бы создал реальный тип и украсил его как Serializable. Затем вы можете сильно ввести свои веб-методы. Хотя для Javascript это ни на йоту не имеет значения, он добавляет к методу некоторую самостоятельную документацию. Любой достаточно опытный программист сможет взглянуть на сигнатуру функции и сказать: «О, это тип Foo! Я знаю, как это должно выглядеть в JSON».

Сказав это, вы можете попробовать JSON.Net для сериализации. Я понятия не имею, сработает ли это

JSON.Net работает нормально. Я бы сказал, что не стоит :), я думаю, что во многих случаях это вполне законно.

aprilchild 01.12.2008 22:56

Увидев, что в MVC используются «выбрасываемые» типы, я вижу несколько убедительных применений. Я думаю, что это очень удобный инструмент, который может быть у вас в ящике для инструментов .Net.

Matthew Whited 07.06.2009 07:21

Я также смягчился по этому поводу, особенно в случае типов, предназначенных только для потребления. Но если объект возвращается на сервер или используется более чем в одном месте, я по-прежнему считаю, что создание типа приведет к меньшему количеству проблем.

Jason Jackson 07.06.2009 20:01

Десериализация в стиле DataContract плохо справляется с полиморфными типами. Вы должны написать свой собственный десериализатор. Слишком много обслуживания кода.

micahhoover 12.01.2015 19:05

Пример использования, в котором сериализация анонимных типов полезна, - это модульные тесты для веб-API.

howcheng 24.02.2016 03:39

Другой вариант использования, я пытаюсь создать функцию веб-службы построения диаграмм, в которой вы просто отправляете данные JSON и структуру конфигурации в одной и той же отправке, сообщая ей, какой столбец - X, а какой столбец - Y ... Поскольку я ничего не знаю о данные, поступающие в API, строгая типизация - это foobar.

Dan Chase 31.01.2019 20:21

Предполагая, что вы используете это для веб-службы, вы можете просто применить к классу следующий атрибут:

[System.Web.Script.Services.ScriptService]

Затем следующий атрибут для каждого метода, который должен возвращать Json:

[ScriptMethod(ResponseFormat = ResponseFormat.Json)]

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

Для стандартной веб-службы ASP [ScriptMethod (ResponseFormat = ResponseFormat.Json)] не требуется в методе, подойдет [WebMethod]. Также вы не должны устанавливать тип возвращаемого значения для объекта, он может и должен быть строго типизирован с несложным (то есть может быть сериализованным) типом.

row1 08.03.2010 11:42

Вы можете попробовать мой ServiceStack JsonSerializer, на данный момент это самый быстрый сериализатор .NET JSON. Он поддерживает сериализацию DataContract, любого типа POCO, интерфейсов, объектов с поздней привязкой, включая анонимные типы и т. д.

Базовый пример

var customer = new Customer { Name = "Joe Bloggs", Age=31 };
var json = customer.ToJson();
var fromJson = json.FromJson<Customer>(); 

Примечание. Используйте Microsofts JavaScriptSerializer только в том случае, если производительность не важна для вас, поскольку мне пришлось исключить его из моих тестов, так как он до 40x-100x медленнее, чем другие сериализаторы JSON.

Я использую MS JavaScriptSerializer в стеке MVC3 для сериализации объектов с небольшими объемами данных. В таких случаях это довольно быстро и занимает меньше миллисекунды, чтобы сделать то, что мне нужно. Сам запрос к БД занимает в 50-100 раз больше времени, поэтому в моей ситуации это не является серьезным узким местом.

Brian 15.10.2012 18:00

Преждевременная оптимизация - это ... ну вы понимаете.

Mathias Lykkegaard Lorenzen 30.08.2014 17:16

Ссылка "самый быстрый сериализатор .NET JSON" - 404ing! К тому же этому ответу более пяти с половиной лет. Есть ли у вас обновления производительности различных сериализаторов .NET JSON?

ErikE 01.04.2016 11:55
public static class JsonSerializer
{
    public static string Serialize<T>(this T data)
    {
        try
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
            var stream = new MemoryStream();
            serializer.WriteObject(stream, data);
            string jsonData = Encoding.UTF8.GetString(stream.ToArray(), 0, (int)stream.Length);
            stream.Close();
            return jsonData;
        }
        catch
        {
            return "";
        }
    }
    public static T Deserialize<T>(this string jsonData)
    {
        try
        {
            DataContractJsonSerializer slzr = new DataContractJsonSerializer(typeof(T));
            var stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonData));
            T data = (T)slzr.ReadObject(stream);
            stream.Close();
            return data;
        }
        catch
        {
            return default(T);
        }
    }
}

Это не сериализует анонимные типы согласно вопросу

Mark Sowul 30.09.2016 21:33

Как уже упоминалось, Newtonsoft JSON.NET - хороший вариант. Вот конкретный пример простой сериализации JSON:

return JsonConvert.SerializeObject(
    new
    {
       DataElement1,
       SomethingElse
    });

Я обнаружил, что это очень гибкая универсальная библиотека.

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

var obj = new {Id = thing.Id, Name = thing.Name, Age = 30};
JavaScriptSerializer serializer = new JavaScriptSerializer();
string json = serializer.Serialize(obj);

Пространство имен: System.Web.Script.Serialization.JavaScriptSerializer

И для десериализации:. . динамический myObject = JsonConvert.DeserializeObject <dynamic> (вывод); . . ссылка: Newtonsoft.json.dll

i31nGo 23.05.2014 14:13

Вы можете использовать Newtonsoft.Json.

var warningJSON = JsonConvert.SerializeObject(new {
                warningMessage = "You have been warned..."
            });

Для тех, кто проверяет это примерно в 2020 году:

Пространство имен Microsoft System.Text.Json - новый король в городе. Что касается производительности, насколько я могу судить, это лучший вариант:

var model = new Model
{
    Name = "Test Name",
    Age = 5
};

string json = JsonSerializer.Serialize(model);

Как отмечали некоторые другие, NewtonSoft.Json также является очень хорошей библиотекой.

Другие вопросы по теме