3

I have to consume a so called web service implemented by a dumb monkey which is returning some garbage after the proper Json response. Something like this:

{
  "Property1": 1,
  "Property2": 2,
  "Property3": 3
}<?xml version='1.0' ?>Maybe some other gibberish nonsense I wish to discard.

Now, I could just search for "<?xml" and split, but I was wondering if I can use a stream reader or something to read up to the closing } and then discard the rest.

I'm using C# and Json.Net.

Alberto Chiesa
  • 7,022
  • 2
  • 26
  • 53
  • Can you guarantee that the substring `" ... }....` ? – Lasse V. Karlsen May 11 '16 at 20:05
  • http://stackoverflow.com/questions/524548/regular-expression-to-detect-semi-colon-terminated-c-for-while-loops/524624#524624 Look at the propsed solution, it's based on counting opening/closing brackets – Gusman May 11 '16 at 20:05
  • I would like a robust solution. Given Json.Net has many advanced readers, I was wondering if using one of them instead of the standard JsonConvert I could get a JToken or something like that. – Alberto Chiesa May 11 '16 at 20:06

2 Answers2

2

You can also set JsonSerializerSettings.CheckAdditionalContent = false to tell the serializer to ignore any content after the end of the deserialized JSON object:

var result = JsonConvert.DeserializeObject<Dictionary<string, long>>(json, new JsonSerializerSettings { CheckAdditionalContent = false })

Oddly enough it is necessary to do this explicitly despite the fact that the default value seems to be false already, since the underlying field is nullable.

dbc
  • 104,963
  • 20
  • 228
  • 340
  • 1
    [Here specifically](https://github.com/JamesNK/Newtonsoft.Json/blob/6d7c94e69fa2f52b91fb22972321cb9b51b9abed/Src/Newtonsoft.Json/JsonConvert.cs#L856-L859) are the lines of code that are the culprit of requiring you to explicitly set the value to false. – Scott Chamberlain May 11 '16 at 22:02
  • @ScottChamberlain - yes, there's something a bit awkward going on here with how this setting interacts with [`JsonReader.SupportMultipleContent`](http://www.newtonsoft.com/json/help/html/P_Newtonsoft_Json_JsonReader_SupportMultipleContent.htm). I have a feeling `CheckAdditionalContent` was added later in such a way that `JsonConvert` would error by default when encountering additional content, but [fragment loops](http://www.newtonsoft.com/json/help/html/ReadMultipleContentWithJsonReader.htm) would not. – dbc May 11 '16 at 22:07
1

I knew there had to be a simple and robust way:

    public T ReadTypeAndDiscardTheRest<T>(string json)
    {
        using (var sr = new StringReader(json))
        using (var jsonReader = new JsonTextReader(sr))
        {
            var token = JToken.Load(jsonReader);

            return token.ToObject<T>();
        }
    }

    [Test]
    public void TestJsonDiscarding()
    {
        var json = @"{""Key"":""a"", ""Value"":""n""}<?xml>aaaa";
        var kp = ReadTypeAndDiscardTheRest<KeyValuePair<string, string>>(json);

        Assert.That(kp.Key, Is.EqualTo("a"));
        Assert.That(kp.Value, Is.EqualTo("n"));
    }

As always, Json.Net FTW.

Alberto Chiesa
  • 7,022
  • 2
  • 26
  • 53