web-dev-qa-db-fra.com

Json: comment décaper correctement les caractères d'échappement avec json.net

J'ai réponse JSON dans le format ci-dessous. 

"[{\\\"JobID\\\":\\\"1\\\",\\\"BillGenerationDate\\\":\\\"4/29/2013 2:53:34 PM\\\",\\\"BillID\\\":\\\"115743\\\",\\\"BillNo\\\":\\\"115743\\\",\\\"CustomerID\\\":\\\"4041705\\\",\\\"PayStatus\\\":\\\"0\\\",\\\"PaymentRequiredStatus\\\":\\\"True\\\",\\\"ProductName\\\":\\\"Epic FBO test\\\",\\\"Description\\\":\\\"Epic Automation 2\\\\r\\\\n\\\",\\\"ProductType\\\":\\\"eBill \\\",\\\"DueType\\\":\\\"-1\\\",\\\"DueDate\\\":\\\"2013-03-15\\\",\\\"Amount\\\":\\\"63.70\\\",\\\"Cost\\\":\\\"\\\"},
{\\\"JobID\\\":\\\"9\\\",\\\"BillGenerationDate\\\":\\\"5/2/2013 10:21:39 AM\\\",\\\"BillID\\\":\\\"115743\\\",\\\"BillNo\\\":\\\"115743\\\",\\\"CustomerID\\\":\\\"4041705\\\",\\\"PayStatus\\\":\\\"0\\\",\\\"PaymentRequiredStatus\\\":\\\"True\\\",\\\"ProductName\\\":\\\"FBO Test Product\\\",\\\"Description\\\":\\\"FBO Product Test\\\",\\\"ProductType\\\":\\\"eBill \\\",\\\"DueType\\\":\\\"-1\\\",\\\"DueDate\\\":\\\"2013-05-01\\\",\\\"Amount\\\":\\\"150.70\\\",\\\"Cost\\\":\\\"\\\"}]

Je crois que json.net gère les caractères d'échappement et j'ai utilisé le code ci-dessous pour le désérialiser dans une collection de dictionnaires. 

var billList = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(contentCorrected);

Mais cette analyse json lève l'exception "Caractère d'identificateur de propriété non valide:. Path '[0]', ligne 1, position 2." Pourrions-nous résoudre ce problème en manipulant la chaîne de réponse JSON?

11

Essayez string contentCorrected = contentCorrected.Replace(@"\", ""); avant le processus de désérialisation.

16
Bijoy K Jose

Le problème se produit lorsque des guillemets valides sont utilisés dans la réponse. Supprimer et/ou remplacer ne résoudra pas ce problème dans tous les cas. Cela m’a également frustré jusqu’à ce que je trouve une solution simple:

var billList = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(@contentCorrected);
0
Jos R.
  1. Supprimez tout le caractère "\" avant de le désérialiser. Utilisez la fonction de remplacement.

    yourJsonString.Replace ("\\\\\", "");

  2. Votre chaîne Json est incomplète ou ne semble pas être de type List<Dictionary<string, string>>". Corrigez le type de fichier que vous souhaitez convertir. J'ai modifié votre fichier json comme suit et cela a fonctionné.

    newJson = "{\" array\":" + yourJsonString + "}"

0
Murugan

LA RÉPONSE COURTE: vous devez tout d'abord désérialiser la chaîne échappée, mais pas vers le type CLR cible, mais la désérialiser sur une autre chaîne:

// Initial example json string:  "\"{\\\"Property1\\\":1988,\\\"Property2\\\":\\\"Some data :D\\\"}\""


// First, deserialize to another string (unescaped string).
string unescapedJsonString = JsonConvert.DeserializeObject<string>(escapedJsonString);
Debug.WriteLine(unescapedJsonString);
// Prints:
// "{\"Property1\":1988,\"Property2\":\"Some data :D\"}"


// Second, deserialize to another string, again (in this case is necessary)
var finalUnescapedJsonString = JsonConvert.DeserializeObject<string>(unescapedJsonString);
Debug.WriteLine(finalUnescapedJsonString);
// This time prints a final, unescaped, json string:
// {"Property1":1988,"Property2":"Some data :D"}


// Finally, perform final deserialization to the target type, using the last unescaped string.
MyClass targetObject = JsonConvert.DeserializeObject<MyClass>(finalUnescapedJsonString);

REPONSE LONGUE (mais intéressante) L'utilisation de string.Replace(... pourrait générer une chaîne non valide, car cela pourrait endommager certains caractères spéciaux nécessitant la désérialisation correcte de la barre oblique inversée.

Ce type de échappé des chaînes sont généralement générés lorsqu’une chaîne qui était déjà une chaîne json, est à nouveau sérialisée (ou même plusieurs fois). Cela provoque quelque chose comme "divers niveaux de sérialisation" (c'est en fait une sérialisation d'une chaîne avec des caractères réservés), et le résultat est des caractères backshash (ou des groupes d'une, deux ou plusieurs barres obliques inverses suivies: \, \\, \\\ ) dispersés sur toute la chaîne. Donc, les retirer correctement ne suffit pas pour les remplacer par empty.

LA BONNE MANIÈRE: Un meilleur moyen d'obtenir une chaîne non échappée serait de faire une première désérialisation en type chaîne (Répétez cette opération plusieurs fois si nécessaire), puis effectuez une désérialisation finale pour cibler le type CLR:

// -- SERIALIZATION --

// Initial object
MyClass originObj = new MyClass { Property1 = 1988, Property2 = "Some data :D" };

// "First level" Of serialization.
string jsonString = JsonConvert.SerializeObject(originObj);
Debug.WriteLine(jsonString);
// Prints: 
// {"Property1":1988,"Property2":"Some data :D"}


// "Second level" of serialization.
string escapedJsonString = JsonConvert.SerializeObject(jsonString);
Debug.WriteLine(escapedJsonString);            
// "{\"Property1\":1988,\"Property2\":\"Some data :D\"}"
// Note the initial and final " character and de backslash characters

// ...
// at this point you could do more serializations ("More levels"), Obtaining as a result more and more backslash followed,
// something like this:
// "\"{\\\"Property1\\\":1988,\\\"Property2\\\":\\\"Some data :D\\\"}\""
// Note that is... very very crazy :D
// ...

// -- DESERIALIZATION --

// First deserialize to another string (unescaped string).
string unescapedJsonString = JsonConvert.DeserializeObject<string>(escapedJsonString);
Debug.WriteLine(unescapedJsonString);
// Prints:
// {"Property1":1988,"Property2":"Some data :D"}

// ...
// at this point you could repeat more deserializations to string, if necessary. For example if you have many backslash \\\
// ...

// Finally, perform final deserialization to the target type, using the last unescaped string.
MyClass targetObject = JsonConvert.DeserializeObject<MyClass>(unescapedJsonString);
0
Johan Alzate

Pour moi, le code ci-dessous fonctionne

string contentCorrected = contentCorrected.Replace(**@"\""", ""**);
0
Prabhat