Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

c# - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

THE SHORT ANSWER: first you need to deserialize the escaped string, but not to the target CLR type, but deserialize to another string:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...