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

Я пытаюсь использовать следующий код для сериализации анонимного типа для 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 документация для других поддерживаемых типы.

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

Ответ 1

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

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

Ответ 2

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

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

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

Ответ 3

Вы можете попробовать мой ServiceStack JsonSerializer его самый быстрый сериализатор .NET JSON на данный момент. Он поддерживает сериализацию DataContract, Any POCO Type, Interfaces, Late-bound, включая анонимные типы и т.д.

Основной пример

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

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

Ответ 4

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


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

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

Ответ 5

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

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

Ответ 6

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

[System.Web.Script.Services.ScriptService]

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

[ScriptMethod(ResponseFormat = ResponseFormat.Json)]

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

Ответ 7

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

var errorJSON = JsonConvert.SerializeObject(new {
                errorMessage = "My error to inform you"
            });

Ответ 8

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);
        }
    }
}