27

I am using the excellent Json.Net library to serialize my entities generated by entity framework. I use the following code to do so :

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

Everything goes well I mean, the objects are correctly serialized except one think : it adds escape characters "\" that makes me having nightmare when deserializing on the client side.

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

Does anybody know why and how I can get rid of these escape characters slash "\" ?

Liam
  • 27,717
  • 28
  • 128
  • 190
Renaud
  • 561
  • 1
  • 5
  • 13
  • @Jon Skeet is more than likely correct, what issue(s) or error message are you getting when deserializing? – PsychoCoder Jan 19 '11 at 01:40
  • 1
    The issue with deserialising is not due to the escape characters (\) but due to the fact that the serialised text starts with "[" and ends with "]". See @Jone Polvora's answer. If you append your serialised text with {"dummyRoot": and append } you will find that it serialises fine. – ajgreyling Jan 17 '17 at 07:45

5 Answers5

34

I suspect it's not actually adding escape characters at all. I suspect you're just looking at the string in a debugger, and that's adding the escaping.

Try dumping it to a file or the console.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
20

I found the reason why I had escape characters in my string ("\"). After serializing my objects, I am returning the JSON string to the client app through a WCF. Apparently, WCF is automatically adding these characters to the string before sending it to the network. It is a default behaviour and is apparently mandatory.

As I didn't want these escape characters, the workaround is to change the return type of the service to Stream and so, returning your JSON string inside a memory stream. It works perfectly and is quite fast.

Liam
  • 27,717
  • 28
  • 128
  • 190
Renaud
  • 561
  • 1
  • 5
  • 13
  • Bah! You specifically said it was adding them at serialisation! Glad you got it fixed though. :) And you can +1 answers you found helpful though I can't remember if you can do that at your level of rep... – Chris Jan 24 '11 at 10:50
  • 11
    The real reason that you are getting the escape characters is because you are manually serializing your return value _and_ WCF is also serializing your (already-serialized) return value as part of its natural behavior. So the JSON ends up with escape characters in it. By returning as a stream you are effectively doing an end-run around the WCF serializer. Another possible solution is to simply return the non-serialized object from your method and let WCF serialize it, but that means not using Json.Net. – Brian Rogers Dec 25 '13 at 21:22
  • 1
    @Brian - you're right. I'm having this same problem, but it's annoying because I want to have a custom converter that is only used by the controller (hence, I can't annotate the class to say "always serialize with this custom converter). If I use the custom converter in the controller logic, I return a string and then WCF re-serializes the data... – Jmoney38 Feb 14 '17 at 17:53
4

It's invalid JSON because the result of serializing a list of objects is an array, i.e., the json will start with a [ and ending with a ]. To fix this, you need to wrap the list of objects in a root object (any instance of a class or an anonymous object), so, the resulting string will start with a { and end with }.

For example:

var output = new List<object>();
var json = JsonConvert.SerializeObject(new { root = output }, Formatting.Indented);
Response.Write(json);
Liam
  • 27,717
  • 28
  • 128
  • 190
Jone Polvora
  • 2,184
  • 1
  • 22
  • 33
  • ellegant! what does one call this C# functionality of creating a object with new { x = y }. I have used this for constructerless instantiating but not like this. – ajgreyling Jan 17 '17 at 07:46
  • yes, it's called anonymous type in C#, very useful when you don't want to create a normal "named" class just for a simple task like this one. – Jone Polvora Jan 17 '17 at 19:12
  • internally the compiler will generate a class for you – Jone Polvora Nov 11 '18 at 21:49
2

Does this one help? I used it in my WebService to return Json content:

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

If strings have a "\" the two "\\" will come back. You can avoid this by using 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");
}
Mickey Mouse
  • 723
  • 6
  • 4
  • While the other answers gave good answers as to *why* the characters were not being escaped, the Unescape solution was a quick and good solution for dealing with a similar issue I was having. – Cantalouping Aug 22 '17 at 02:31
1

I should note that you have not completely quoted the outputted stuff (I got the url to work in your answer - that should have been edited into your question rather than put as an answer). The string I got back in a file was this:

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

the key thing to me is that there are unescaped quotes at the front and end which makes me think that whatever is outputting it is deciding it needs to be quoted and if you are surrounding it in quotes you ahve to escape the quotes that are inside it.

Without seeing the full output its hard to say if the problem is in teh code you've quoted above to generate the JSON or if there is a problem at a later step of processing this which is causing the quoting. Have you debugged and confirmed that the output of your serialize call is definitely producing the escaped version rather than it being done at a later stage potentially? If you're not used to the debugger then pay attention to Jon Skeet's suggest of dumping it to file or console to make sure there is no confusion that way.

Chris
  • 27,210
  • 6
  • 71
  • 92
  • Chris, thx for your answer. I verified with the debugger and it is, indeed, adding the quotes at the serialization, not in a later step. Nevertheless, I tried the same code in an other project and for a reason I don't know, it doesn't add the quotes ... Could it be the type of the object I am serializing that produce these quotes by the Json.net library ? – Renaud Jan 20 '11 at 13:23
  • I've not actually used the Json.net library myself so I am not sure I can provide any more advice. You can try with different objects and different data in those objects to see if it makes a difference. I'm a bit stumped as to why it would do that though, I can't think of any situation in which you would ever want it to. Out of interest if you run it straight back through teh deserialise method does it work as expected? Idly wondering if there may be some kind of bug here.. – Chris Jan 20 '11 at 15:30