Deserialize Json with invalid markup

11,536

Solution 1

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.

Solution 2

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.

Share:
11,536
Skintkingle
Author by

Skintkingle

Full stack software developer from data consumption to presentation using WPF and C# with modern technologies.

Updated on June 04, 2022

Comments

  • Skintkingle
    Skintkingle almost 2 years

    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.