C# String Array Deserialization Problems - c#

I'm having a really strange issue serializing to an MSMQ and back.
The object being serialized contains a string array; one of the strings in the array contains spaces and carriage returns ("\r\n"). The object is constructed fine and seems to serialize without a problem, but when I deserialize it (in another project), the array now contains an item for every individual word and space.
i.e.:
the array { "first", "this is a test string" }
becomes { "first", "this", "", "is", "", "a", "", "test, "", "string" }
I have no idea what's going on... as far as the serialization, I'm using MessageQueue.Send() and System.XML.Serialization.
Any help?

\r\n seem to be messing up your serialization. Can you intercept the serialization and replace them with another set of characters before dehydrating them and then adding them back when re-hydrating?

What does the serialized xml look like? If you look at the actual xml output, you should be able to tell whether it is the serializer or deserializer that is causing the problem, which would certainly help in attempting a fix.
With that said, i will say that i very often serialize objects that contain the exact formation of data you are specifying and i am fairly certain i've never seen this behavior.
Perhaps a code example to repro the issue would be helpful.

Related

Deserializing JSON with Newtonsoft with quotes in a value

I am retrieving JSON from an API and have the following problem:
Some Json-values look like this and cannot be serialized the standard way
"key": "This is just a "dummy" value to show the problem",
The problem are the quotes around dummy. Newtonsoft obviously thinks the value ends with the quote before dummy, but it actually ends after problem.
Is there a way to ignore those quotes or somehow remove them automatically?
I've tried to remove them with a StringBuilder and String-Replace, but that didn't work because such a pattern occures mutliple times in the JSON-File and sometimes the nested quotes quote a single word, sometimes a whole sentence.
The whole JSON from the API has around 50.000 lines, so it's impossible to correct the error by hand.
Can this be solved somehow in C#?
Update: You have to write a custom parser to parse since its clearly not JSON then. What you have to do is fix the serialized object before you deseriliaze it. You have to iterate through the entire string and remove the unrequired quotes.
An example would be when the value property of a JSON ends and next one begins there is a comma character in the middle.
Its basically a huge nested if condition, to fix this.
Original Answer
As you can see, it does not parse as an valid JSON. You have to represent quotes as below. If its not someting in your control, you have to come up with a custom parser.

Deserializing JSON string into string array

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.

Deserialize Json with invalid markup

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.

Need help using a "root"-less JSON object with Json.Net and JArrays

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.

Json.Net unexpected characters ("\") when serializing my entities

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.

Categories

Resources