Как сериализовать анонимный тип C # в строку JSON? - PullRequest
156 голосов
/ 01 декабря 2008

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

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

Тем не менее, я получаю следующее исключение при выполнении:

Тип <> F__AnonymousType1`3 [System.Int32, System.Int32, System.Object []] ' не может быть сериализовано. Рассмотрим маркировку это с DataContractAttribute атрибут, и маркировка всех его члены, которые вы хотите сериализовать с Атрибут DataMemberAttribute. Увидеть Microsoft .NET Framework документация для других поддерживаемых типы.

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

Ответы [ 7 ]

154 голосов
/ 01 декабря 2008

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

JavaScriptSerializer serializer = new JavaScriptSerializer();
var output = serializer.Serialize(your_anon_object);
66 голосов
/ 10 мая 2012

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

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

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

13 голосов
/ 18 августа 2010

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

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

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

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

11 голосов
/ 01 декабря 2008

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

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

8 голосов
/ 23 мая 2014

Самый быстрый способ, который я нашел, был таким:

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

1 голос
/ 02 декабря 2008

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

[System.Web.Script.Services.ScriptService]

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

[ScriptMethod(ResponseFormat = ResponseFormat.Json)]

И установить тип возвращаемого значения для методов как «объект»

0 голосов
/ 28 марта 2011
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);
        }
    }
}
...