¿Cómo serializo un tipo anónimo de C# en una cadena JSON?


Estoy intentando usar el siguiente código para serializar un tipo anónimo a JSON:

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

Sin embargo, obtengo la siguiente excepción cuando se ejecuta:

Tipo "f _ _ AnonymousType1 " 3 [System.Int32,System.Int32,System. Object []]" no se puede serializar. Considere marcar con el DataContractAttribute atributo, y marcando todos sus miembros que desea serializar con el Atributo DataMemberAttribute. Ver Microsoft. NET Framework documentación para otros servicios compatibles tipo.

No puedo aplicar atributos a un tipo anónimo (que yo sepa). ¿Hay otra manera de hacer esta serialización o me estoy perdiendo algo?

Author: Johnno Nolan, 2008-12-01

7 answers

Pruebe el JavaScriptSerializer en lugar del DataContractJsonSerializer

JavaScriptSerializer serializer = new JavaScriptSerializer();
var output = serializer.Serialize(your_anon_object);
 151
Author: Nick Berardi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-08 07:50:44

Como otros han mencionado, Newtonsoft JSON.NET es una buena opción. Aquí hay un ejemplo específico para la serialización simple de JSON:

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

He encontrado que es una biblioteca muy flexible y versátil.

 61
Author: Matthew Nichols,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-09 21:56:26

Puede probar mi ServiceStack JsonSerializer es el serializador JSON de.NET más rápido en este momento. Admite serialización de DataContract, Cualquier Tipo POCO, Interfaces, objetos de enlace tardío, incluidos tipos anónimos, etc.

Ejemplo básico

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

Nota: Solo use Microsofts JavaScriptSerializer si el rendimiento no es importante para usted, ya que he tenido que dejarlo fuera de mis puntos de referencia ya que es hasta 40x-100x más lento que los otros serializadores JSON.

 12
Author: mythz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-28 05:37:20

Yo diría que no debería serializar un tipo anónimo. Conozco la tentación aquí; desea generar rápidamente algunos tipos desechables que solo se van a usar en un entorno de tipo suelto, también conocido como Javascript, en el navegador. Aún así, crearía un tipo real y lo decoraría como Serializable. A continuación, puede escribir fuertemente sus métodos web. Si bien esto no importa un ápice para Javascript, sí agrega algo de auto-documentación al método. Cualquier razonablemente programador experimentado será capaz de mirar la firma de la función y decir, " Oh, este es el tipo Foo! Sé cómo debería verse eso en JSON."

Habiendo dicho eso, podrías intentar JSON.Net para hacer la serialización. No tengo idea si funcionará

 11
Author: Jason Jackson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-01 23:20:42

La forma más rápida que encontré fue esta:

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

Espacio de nombres: System.Web.Script.Serialización.JavaScriptSerializer

 7
Author: i31nGo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-29 18:32:01

Asumiendo que está usando esto para un servicio web, solo puede aplicar el siguiente atributo a la clase:

[System.Web.Script.Services.ScriptService]

Luego el siguiente atributo para cada método que debe devolver Json:

[ScriptMethod(ResponseFormat = ResponseFormat.Json)]

Y establece el tipo de retorno para que los métodos sean "object"

 1
Author: Paul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-01 21:33:42
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);
        }
    }
}
 -1
Author: harryovers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-28 15:20:56