Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json: how to properly strip the escape characters with json.net

I have json response in the below format.

"[{\\\"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\\\":\\\"\\\"}]

I believe json.net handles the escape characters and I used the below code to deserialize it to a dictionary collection.

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

But this json parsing throws exception "Invalid property identifier character: . Path '[0]', line 1, position 2." Could we solve this by manipulating the json response string?

like image 294
Sharon C Lawrence Avatar asked May 02 '13 06:05

Sharon C Lawrence


People also ask

How remove all escape characters from JSON string?

I have found that the easiest and best way to remove all escape characters from your JSON string, is to pass the string into Regex. Unescape() method. This method returns a new string with no ecapes, even \n \t etc, are removed.

How do you escape a newline character in JSON?

JSON strings do not allow real newlines in its data; it can only have escaped newlines. Snowflake allows escaping the newline character by the use of an additional backslash character.

What characters should be escaped in JSON?

In JSON the only characters you must escape are \, ", and control codes. Thus in order to escape your structure, you'll need a JSON specific function.

How do I remove an escape character from a JSON in Java?

replaceAll("\\",""); But do note that those escape characters in no way make the JSON invalid or otherwise semantically different -- the '/' character can be optionally escaped with '\' in JSON.


1 Answers

THE SHORT ANSWER: first you need to deserialize the escaped string, but not to the target CLR type, but deserialize to another string (repeat if necessary); then, it is deserialized to the target type:

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

LONG ANSWER (but interesting) Using string.Replace(... could generate an invalid string, because it could damage certain special characters that needed the backslash to be deserialized correctly .

This type of escaped strings are usually generated when a string that was already a json string, its serialized again (or even more times). This causes something like "various levels of serialization" (it really is a serialization of a string with reserved characters), and the result is backshash characters (or groups of one, two or more backslash followed: \, \, \\\) scattered all over the string. So, to remove them correctly is not enough to replace them by empty.

THE RIGHT WAY: A better way to get a unescaped string would be to do a first deserialization to string type (Repeat this several times if necessary), And then do a final deserialization to target CLR type:

// -- 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);
like image 61
Johan Alzate Avatar answered Sep 25 '22 03:09

Johan Alzate