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 "\" ?
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.
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.
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);
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");
}
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.
Related
I got some trouble with a problem when use Newtonsoft json.net to deserialize json string to dictionary. It 's a case of my json string have some special character.
string jsonString = "{\"name\":\"Jones Smith\",\"age\":\"20\",\"description\":\"The one live with \"ALIGATOR\"\"}";
Dictionary<string, object> dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString);
I try to find a solution in the use of json.net but i not found. So the FINAL plan is remove that "characters". So, what is the best solution for this case?
I think you can't do very much in your situation besides changing the format at the origin. The problem with your input is that there are " characters escaped the same way once in your json directly and once in your json values.
Consider the following part: "description":"The one live with "ALIGATOR""
How should a deserializer know which " should be considered part of the value or part of the json format?
I got the answer, like the last comment, that 's not valid JSON, below is valid JSON
{"name":"Jones Smith","age":"20","description":"The one live with \"ALIGATOR\""}
And all i can do is add '\' before special characters if the value of field description is "The one live with "ALIGATOR"" to make a valid JSON and convert to c# like this:
string jsonString = {\"name\":\"Jones Smith\",\"age\":\"20\",\"description\":\"The one live with \\"ALIGATOR\\"\"}
I'm somehow having troubles deserializing a json string into a simple List or string[] (I don't care which).
As of what I know, this is how to do this job:
JsonConvert.DeserializeObject<List<string>>(jsonString);
Here I am getting a RuntimeBinderException. It complains about the parameter, although my json string is valid and simple: a:1:{i:0;s:10:"Sahibinden";}
What you have isn't JSON is a serialized PHP object. There have been some tools that work well with this in C# but there isn't native support. If you own the PHP, then convert the object/array to JSON first. If not try the information on this question: https://stackoverflow.com/a/1923626/474702
Your JSON is invalid. Problems:
a:1 should be inside an object bracket of {}
The : before the { is invalid, you need a , there
The ; just after i:0 is invalid, you need a comma there
You repeat the mistake described in 1. and 2. inside your {} brackets as well
Solution: You need to read about JSON and make sure you understand its syntax.
I'm currently trying to tackle a situation where we have invalid Json that we are trying to deserialize. The clinch point is we're supplied Json where property assignment is declared with an = instead of a : character.
Example Json:
{
"Field1" = "Hello",
"Field2" = "Stuff",
"Field3" = "I am non-Json Json, fear me",
"Field4" = 8
}
Has anyone had any luck using Json.Net to deserialize this into an object of relating structure into C# where = is in use instead of :
I've been trying to write a JsonConverter to read past the = but it always complains it's got an = instead of a : and throws an exception with the message "Expected ':' but got: =. Path ''".
I don't see any way past this except for writing my own deserialization process and not using the Json.Net library. which sucks for something so close to being valid Json (But I suppose is fair enough as it is invalid)
When reader.ReadAsString(); is hit it should read Field1 out but obviously it hasn't met its friend the : yet and so proceeds to fall over saying "what the hell is this doing here?!". I've not got any JsonConverter implementation examples because there's really not much to show. just me attempting to use any of the "Read..." methods and failing to do so.
If property assignment is declared with an = instead of a : character then it is not JSON.
If you don't expect any = in the values of the object then you can do a
string json = invalidData.Replace("=", ":");
and then try to parse it.
As mentioned by #Icepickle, there are risks involved in doing this.
My answer works as a quick fix/workaround, but you will eventually need to make sure that the data you are receiving is valid JSON.
There is no point in trying to deserialize invalid JSON.
As suggested by others, the easiest way to get around this issue is to use a simple string replace to change = characters to : within the JSON string prior to parsing it. Of course, if you have any data values that have = characters in them, they will be mangled by the replacement as well.
If you are worried that the data will have = characters in it, you could take this a step further and use Regex to do the replacement. For example, the following Regex will only replace = characters that immediately follow a quoted property name:
string validJson = Regex.Replace(invalidJson, #"(""[^""]+"")\s?=\s?", "$1 : ");
Fiddle: https://dotnetfiddle.net/yvydi2
Another possible solution is to alter the Json.Net source code to allow an = where a : normally appears in valid JSON. This is probably the safest option in terms of parsing, but requires a little more effort. If you want to go this route, download the latest source code from GitHub, and open the solution in Visual Studio 2015. Locate the JsonTextReader class in the root of the project. Inside this class is a private method called ParseProperty. Near the end of the method is some code which looks like this:
if (_chars[_charPos] != ':')
{
throw JsonReaderException.Create(this, "Invalid character after parsing property name. Expected ':' but got: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
}
If you change the above if statement to this:
if (_chars[_charPos] != ':' && _chars[_charPos] != '=')
then the reader will allow both : and = characters as separators between property names and values. Save the change, rebuild the library, and you should be able to use it on your "special" JSON.
Is there any way to handle newlines in JSON.NET. I have some data coming back with Carriage Return Line Feed in it and Json.Net is just leaving it raw in the return value. Is there a way to force Json.Net to encode this for Json. I assumed this would happen by default but it is not happening for me. Maybe I am missing something else.
I am using Json.Net in a MVC4 WebApi project if that matters.
My data is coming back with \r\n in the string such as
"Keywords": "These are my keywords.\r\n\r\n\r\nThis is a second line...\r\n\r\nThis is a third line. ...\r\n\r\n\r\nThis is a 4th line ..."
From what I understand, that should be
\\r\\n. It could be a problem with the data I am returning, but I just wanted to see what JSON.NET should be doing with this.
For me, the problem was that even if the serialized Json object looked correct in the debugger, when I write it to file it gets all these literals added (i.e. backslashes are added).
What worked was to parse the obtained json as a Token, and then use the token instead.
For example:
// Serialize and convert to Token
string json = Newtonsoft.Json.JsonConvert.SerializeObject(someObject);
var token = JToken.Parse(json);
// Save to file
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(filepath, token);
I honestly do not understand why this would be needed, or if there is a better way around this. Feedback in comment is appreciated.
You can serialize your object with the option Formatting.Indented.
Like this:
string yourJsonString = JsonConvert.SerializeObject(yourObject, Formatting.Indented, new JsonSerializerSettings { });
I think this should work.
Regards.
I'm using the ExportAPI from MailChimp. It sends back a "root"-less Json string like so:
["Email Address", "First Name", "Last Name"]
["jeff#mydomain.com", "Jeff", "Johnson"]
["tubbs#mydomain.com", "Tubbs", "McGraw"]
No brackets, nothing- just a couple of arrays. Loading it into a JArray only picks up the first object:
JArray jsonArray = new JArray.Parse(jsonResponse);
Console.WriteLine(jsonArray);
//Outputs:
//Email Address
//First Name
//Last Name
I'm hoping to copy the contents of the string into a database and need to access the response with LINQ. Any suggestions as to the correct way to work with a Json Object like I've shown above (using Json.net or otherwise?)
Pad the string with a root element, just add '[' and ']'?
This behavior is actually completely on purpose as mentioned in the docs. The reasoning is that a full dump of a list's data can easily be way too large to consistently fit it in memory and parse it. As such, and given the return format, you're expected to use a newline as the delimiter (or read it off the wire that way), parse each object individually, and then do whatever you need with them.
I am not familiar with doing that in C#/Linq, but the PHP example on the docs page does exactly that.