2008-12-01 22 views
145

Estoy intentando utilizar el siguiente código para serializar un tipo anónimo a JSON:¿Cómo serializo un tipo anónimo C# en una cadena JSON?

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

Sin embargo, me sale el siguiente excepción cuando se ejecuta esto:

Tipo '<> f__AnonymousType1 `3 [System.Int32, System.Int32, System.Object []] ' no se pueden serializar. Considere marcar con el atributo DataContractAttribute y marcar todos sus miembros que desee serializar con el atributo DataMemberAttribute. Consulte la documentación de Microsoft .NET Framework para otros tipos compatibles .

No puedo aplicar atributos a un tipo anónimo (hasta donde yo sé). ¿Hay otra forma de hacer esta serialización o me falta algo?

Respuesta

148

Prueba el JavaScriptSerializer en lugar de la DataContractJsonSerializer

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

Uno de enganche sin embargo. JavaScriptSerializer ha quedado en desuso. – Biswanath

+16

Trackback, parece que fue desaprobado en SP1. – Biswanath

+7

por algo tan obsceno, parece estar siendo usado en muchos frameworks nuevos de Microsoft, incluido MVC. http://aspnet.codeplex.com/SourceControl/changeset/view/21528#266491 –

10

Yo diría que no debe ser un anónimo serializando tipo. Conozco la tentación aquí; Desea generar rápidamente algunos tipos desechables que simplemente se utilizarán en un entorno de tipo libre, como Javascript en el navegador. Aún así, crearía un tipo real y lo decoraría como Serializable. Entonces puede escribir fuertemente sus métodos web. Si bien esto no importa un ápice de Javascript, sí agrega algo de auto-documentación al método. Cualquier programador con experiencia razonable podrá ver la firma de la función y decir: "¡Oh, esto es tipo Foo! Sé cómo debería verse en JSON".

Habiendo dicho eso, puede intentar JSON.Net para hacer la serialización. No tengo idea de si va a trabajar

+3

JSON.Net funciona bien. Argumentaría que no deberías :), creo que es bastante legítimo en muchos casos. – aprilchild

+2

Después de ver los tipos de "tirar" que se usan en MVC, puedo ver algunos usos convincentes. Creo que es una herramienta muy útil para tener en su caja de herramientas .Net. –

+12

Este es un punto que también he suavizado, especialmente en el caso de los tipos de solo consumo. Pero si el objeto realiza un viaje de regreso al servidor o se usa en más de una ubicación, sigo creyendo que crear un tipo generará menos problemas. –

1

Suponiendo que está usando esto para un servicio web, sólo puede aplicar el atributo siguiente a la clase:

[System.Web.Script.Services.ScriptService] 

A continuación, el siguiente atributo para cada método que debe devolver JSON:

[ScriptMethod(ResponseFormat = ResponseFormat.Json)] 

Y establecer el tipo de cambio de los métodos que sean "objeto"

+0

Para un servicio web ASP estándar [ScriptMethod (ResponseFormat = ResponseFormat.Json)] no es necesario en el método, [WebMethod] lo hará. Además, no debe establecer el tipo de devolución en el objeto, puede y debe estar fuertemente tipeado con un tipo no complejo (es decir, puede ser serializado). – row1

12

puede intentar mi ServiceStack JsonSerializer que es el fastest .NET JSON serializer por el momento. Es compatible con la serialización DataContract de, Cualquier POCO Tipo, interfaces, objetos enlazado en tiempo, incluyendo los 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: Sólo utilice Microsoft de JavaScriptSerializer si el rendimiento no es importante para usted como yo' Tuve que dejarlo fuera de mis puntos de referencia ya que es hasta 40x-100x más lento que los otros serializadores JSON.

+7

Estoy usando MS JavaScriptSerializer en la pila MVC3 para serializar objetos con pequeñas cantidades de datos. Es bastante rápido en estos casos, tomando menos de un milisegundo para hacer lo que necesito. La consulta DB en sí misma tarda de 50x a 100x más, por lo que no es realmente un cuello de botella significativo en mi situación. – Brian

+2

La optimización prematura es ... Bueno, ya sabes. –

+0

"¡el serializador más rápido de .NET JSON" está 404ing! Además, esta respuesta tiene más de 5 1/2 años. ¿Tiene una actualización sobre el rendimiento de varios serializadores .NET JSON? – ErikE

-1
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); 
     } 
    } 
} 
+0

Esto no serializa tipos anónimos según la pregunta –

58

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

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

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

7

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

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.Serialization.JavaScriptSerializer

+1

Y para la deserialización: . . myObject dinámico = JsonConvert.DeserializeObject (salida); . . Referencia : Newtonsoft.json.dll – i31nGo

Cuestiones relacionadas