2011-01-18 13 views
16

Estoy utilizando la excelente biblioteca Json.Net para serializar mis entidades generadas por entidad framework. Yo uso el siguiente código para hacerlo:Json.Net caracteres inesperados ("") al serializar mis entidades (Entity framework)

using (MyVoucherEntities context = new MyVoucherEntities()) 
{ 
    List<MyObject> list = context.MyObjects.ToList(); 
    string json = JsonConvert.SerializeObject(list); 
} 

Todo va bien quiero decir, los objetos se serializan correctamente excepto uno pensar: se añade caracteres de escape "\" que me hace tener pesadillas al deserializar en el lado del cliente.

[ 
    { 
     \"$id\": \"1\", 
     \"CreationDate\": \"\\\/Date(1293186324257+0000)\\\/\", 
     \"ImageUrl\": \"http:\/\/www.google.com\", 
     \"Title\": \"Here is a title\" 
    } ] 

¿Alguien sabe por qué y cómo puedo deshacerme de estos caracteres de escape barra "\"?

+0

@Jon Skeet es más que probable que sea correcto, ¿qué problema (s) o mensaje de error está recibiendo al deserializar? – PsychoCoder

+0

El problema con la deserialización no se debe a los caracteres de escape (\) sino al hecho de que el texto serializado comienza con "[" y finaliza con "]". Ver la respuesta de @Jone Polvora. Si agrega su texto serializado con {"dummyRoot": y append}, encontrará que se serializa correctamente. – ajgreyling

Respuesta

13

Ok, encontré la razón por la que tenía caracteres de escape en mi cadena ("\") ... Después de serializar mis objetos, devuelvo la cadena json a la aplicación del cliente a través de un WCF. Aparentemente, WCF agrega automáticamente estos caracteres a la cadena antes de enviarla a la red. Es un comportamiento predeterminado y aparentemente obligatorio.

Como no quería estos caracteres de escape, la solución consiste en cambiar el tipo de devolución del servicio a Stream y, por lo tanto, devolver la cadena json dentro de una secuencia de memoria. Funciona perfectamente y es silencioso rápido.

Thx @Jon Skeet y @Chris por su ayuda!

+0

Bah! ¡Usted dijo específicamente que los estaba agregando en la serialización! Me alegro de que lo hayas reparado. :) Y puedes +1 respuestas que encontraste útiles aunque no puedo recordar si puedes hacerlo en tu nivel de representante ... – Chris

+7

La verdadera razón por la que estás obteniendo los caracteres de escape es porque estás serializando manualmente tu valor de retorno _and_ WCF también está serializando su valor de retorno (ya serializado) como parte de su comportamiento natural. Entonces el JSON termina con caracteres de escape en él. Al regresar como una secuencia, se está realizando un análisis de finalización del serializador de WCF. Otra solución posible es simplemente devolver el objeto no serializado de su método y dejar que WCF lo serialice, pero eso significa no usar Json.Net. –

+0

@Brian - tienes razón. Estoy teniendo el mismo problema, pero es molesto porque quiero tener un convertidor personalizado que solo use el controlador (por lo tanto, no puedo anotar la clase para decir "siempre serializar con este convertidor personalizado"). Si uso el convertidor personalizado en la lógica del controlador, devuelvo una cadena y, a continuación, WCF vuelve a serializar los datos ... – Jmoney38

21

Sospecho que no es en realidad añadiendo caracteres de escape. Sospecho que solo está mirando la cadena en un depurador, y que es agregando el escape.

Intente descargarlo en un archivo o la consola.

+0

Volcar a un cuadro de texto de formulario funcionó para mí también. gran consejo, gracias –

1

Debo señalar que no ha citado por completo las publicaciones (obtuve la url para trabajar en su respuesta, que debería haber sido editada en su pregunta en lugar de ponerla como respuesta). La cadena llegué en un archivo fue la siguiente:

"[{\"$id\":\"1\",\"CreationDate\":\"\\\/Date(1293186324257+0000)\\\/\",\"ImageUrl\":\"http:\/\/www.c-tina.com\/MyVoucherAdmin\/Images\/shop22\/burger.jpg\",\"Title\":\"Get one burger for free\",\"Description\":\"Bla lbzlfpzkfgmzke\\rdmjdgmj\\r\\r\\rlgfpzkegmkzepk\",\"ShopId\":22,\"PromotionId\":15,\"Shop\":null,\"Features\":[],\"SingleStats\":[],\"WhatsHots\":[],\"EntityKey\":{\"$id\":\"2\",\"EntitySetName\":\"Promotions\",\"EntityContainerName\":\"MyVoucherEntities\",\"EntityKeyValues\":[{\"Key\":\"PromotionId\",\"Type\":\"System.Int32\",\"Value\":\"15\"}]}}]" 

la clave para mí es que no son citas sin escape en la parte delantera y al final que me hace pensar que lo que está dando salida que es decidir que necesita ser citado y si lo rodeas entre comillas, tienes que escapar de las citas que están dentro de él.

Sin ver la salida completa es difícil decir si el problema está en el código que ha comentado anteriormente para generar el JSON o si hay un problema en un paso posterior del proceso que está causando la cita. ¿Ha depurado y confirmado que el resultado de su llamada de serialización definitivamente está produciendo la versión escapada en lugar de hacerlo en una etapa posterior potencialmente? Si no está acostumbrado al depurador, preste atención a la sugerencia de Jon Skeet de descargarlo en archivos o consolas para asegurarse de que no haya confusión de esa manera.

+0

Chris, gracias por su respuesta. Lo verifiqué con el depurador y, de hecho, está agregando las comillas en la serialización, no en un paso posterior. Sin embargo, probé el mismo código en otro proyecto y por una razón que no sé, no agrega las comillas ... ¿Podría ser el tipo de objeto que estoy serializando que produce estas citas por Json? biblioteca de red? – Renaud

+0

No he usado realmente la biblioteca Json.net, así que no estoy seguro de poder brindar más consejos. Puede probar con diferentes objetos y diferentes datos en esos objetos para ver si hace una diferencia. Sin embargo, estoy un poco perplejo acerca de por qué haría eso, no puedo pensar en ninguna situación en la que alguna vez quisieras. Fuera de interés si lo ejecuta directamente a través del método de deserialización ¿funciona como se esperaba? Me pregunto si puede haber algún tipo de error aquí ... – Chris

1

¿Esto ayuda? Lo utilicé en mi WebService para devolver contenido JSON:

private HttpContent ConvertToJsonContent(object content) 
{ 
    string jsonObject = JsonConvert.SerializeObject(content, Newtonsoft.Json.Formatting.Indented); 
    return new StringContent(jsonObject, Encoding.UTF8, "application/json"); 
} 

Si las cadenas tienen un "\" los dos "\\" va a volver. Esto se puede evitar mediante el uso de Unescape

private HttpContent ConvertToJsonContent(object content) 
{ 
    string jsonObject = Regex.Unescape(JsonConvert.SerializeObject(content, Newtonsoft.Json.Formatting.Indented)); 
    return new StringContent(jsonObject, Encoding.UTF8, "application/json"); 
} 
+0

Mientras que las otras respuestas dieron buenas respuestas en cuanto a * por qué * los personajes no se habían escapado, la solución de Unescape fue rápida y buena solución para lidiar con un problema similar al que estaba teniendo. – Cantalouping

2

Es JSON válido porque el resultado de la serialización de una lista de objetos es una matriz, es decir, el JSON se iniciará con una '[' y termina con un ']'. Para solucionarlo, debe envolver la lista de objetos en un objeto raíz (cualquier instancia de una clase o un objeto anónimo), por lo tanto, la cadena resultante comenzará con un '{' y terminará con '}'. Por ejemplo: var output = new List<object>(); var json = JsonConvert.SerializeObject(new { root = output }, Formatting.Indented); Response.Write(json);

+0

ellegant! qué se llama una funcionalidad de C# para crear un objeto con el nuevo {x = y}. Lo he usado para crear instancias sin constructores pero no así. – ajgreyling

+0

sí, es llamado tipo anónimo en C#, muy útil cuando no desea crear una clase "nombrada" normal solo para una tarea simple como esta. –

Cuestiones relacionadas