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





Попробуйте JavaScriptSerializer вместо DataContractJsonSerializer
JavaScriptSerializer serializer = new JavaScriptSerializer();
var output = serializer.Serialize(your_anon_object);
Trackback, похоже, устарел в SP1.
для чего-то столь навязчивого, похоже, он используется во многих новых фреймворках Microsoft, включая MVC. aspnet.codeplex.com/SourceControl/changeset/view/21528#26649 1
Отлично подходит для отладки в тестовом проекте с фиктивными данными.
Как включить это в проект, отличный от asp.net (консольное приложение)?
@Alxandr: Вам нужно будет сослаться на System.Web.Extensions.dll и добавить оператор using System.Web.Script.Serialization;.
Проблема @randomgui заключалась в том, что тип вывода проекта был установлен на профиль клиента.
Как только это выполняется, вывод имеет тип string ... Как можно вернуть это как фактический объект json, скажем, в приложении MVC4, используя что-то вроде "return Json (output);"
Обратите внимание, что это с 2008 года. Сегодня я бы сказал, что сериализатор должен быть встроен и что вы, вероятно, можете использовать атрибуты swagger +, чтобы информировать потребителей о вашей конечной точке и возвращать данные.
Я бы поспорил, что вы не должен сериализовать анонимный тип. Я знаю искушение здесь; вы хотите быстро сгенерировать некоторые одноразовые типы, которые просто будут использоваться в среде с произвольным набором типов, известной как Javascript в браузере. Тем не менее, я бы создал реальный тип и украсил его как Serializable. Затем вы можете сильно ввести свои веб-методы. Хотя для Javascript это ни на йоту не имеет значения, он добавляет к методу некоторую самостоятельную документацию. Любой достаточно опытный программист сможет взглянуть на сигнатуру функции и сказать: «О, это тип Foo! Я знаю, как это должно выглядеть в JSON».
Сказав это, вы можете попробовать JSON.Net для сериализации. Я понятия не имею, сработает ли это
JSON.Net работает нормально. Я бы сказал, что не стоит :), я думаю, что во многих случаях это вполне законно.
Увидев, что в MVC используются «выбрасываемые» типы, я вижу несколько убедительных применений. Я думаю, что это очень удобный инструмент, который может быть у вас в ящике для инструментов .Net.
Я также смягчился по этому поводу, особенно в случае типов, предназначенных только для потребления. Но если объект возвращается на сервер или используется более чем в одном месте, я по-прежнему считаю, что создание типа приведет к меньшему количеству проблем.
Десериализация в стиле DataContract плохо справляется с полиморфными типами. Вы должны написать свой собственный десериализатор. Слишком много обслуживания кода.
Пример использования, в котором сериализация анонимных типов полезна, - это модульные тесты для веб-API.
Другой вариант использования, я пытаюсь создать функцию веб-службы построения диаграмм, в которой вы просто отправляете данные JSON и структуру конфигурации в одной и той же отправке, сообщая ей, какой столбец - X, а какой столбец - Y ... Поскольку я ничего не знаю о данные, поступающие в API, строгая типизация - это foobar.
Предполагая, что вы используете это для веб-службы, вы можете просто применить к классу следующий атрибут:
[System.Web.Script.Services.ScriptService]
Затем следующий атрибут для каждого метода, который должен возвращать Json:
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
И установите для методов возвращаемый тип "объект".
Для стандартной веб-службы ASP [ScriptMethod (ResponseFormat = ResponseFormat.Json)] не требуется в методе, подойдет [WebMethod]. Также вы не должны устанавливать тип возвращаемого значения для объекта, он может и должен быть строго типизирован с несложным (то есть может быть сериализованным) типом.
Вы можете попробовать мой 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 раз больше времени, поэтому в моей ситуации это не является серьезным узким местом.
Преждевременная оптимизация - это ... ну вы понимаете.
Ссылка "самый быстрый сериализатор .NET JSON" - 404ing! К тому же этому ответу более пяти с половиной лет. Есть ли у вас обновления производительности различных сериализаторов .NET JSON?
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);
}
}
}
Это не сериализует анонимные типы согласно вопросу
Как уже упоминалось, 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
Вы можете использовать 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 также является очень хорошей библиотекой.
Но есть одна загвоздка. JavaScriptSerializer устарел.