3

I have a string that starts with a JSON object but after the end of which the string goes on (something like {"a":"fdfsd","b":5}ghresd). The text afterward can contain any character and the JSON can be anything allowed for a JSON.

I would like to deserialize the JSON object and know where it ends because I want to process the rest of the string afterward, how do I do that, preferably using Newtonsoft.Json?

Useme Alehosaini
  • 2,998
  • 6
  • 18
  • 26
Tobias Brohl
  • 479
  • 6
  • 25
  • You might find the answers to my earlier, related question helpful, although in that case I was working in JavaScript: https://stackoverflow.com/questions/54608178/how-do-i-parse-json-sprinkled-unpredictably-into-a-string – R. Davidson Apr 03 '19 at 19:57
  • Does the string contain } after the json-object? Hopefully not. Then you could use Parse with yourString.SubString(0,yourString.LastIndexOf('}')) as parameter. – Nikolaus Apr 03 '19 at 19:58
  • How about getting everything from the first `{` and then the last index of `}`... this could be your json and the rest you can deal with then. Also you could verify it's valid json as well using `JToken.Parse`... – Trevor Apr 03 '19 at 19:58
  • 1
    You can discard the characters after the end as shown in [Discarding garbage characters after json object with Json.Net](https://stackoverflow.com/q/37172263/3744182), however `JsonTextReader` buffers its content, and doesn't have any mechanism to report the current character position. – dbc Apr 03 '19 at 20:01
  • @R.Davidson I was aware of the possibility to do this, but hoped for an easier solution, thanks anyway – Tobias Brohl Apr 03 '19 at 20:01
  • @TobiasBrohl true, but what about the additional content the OP needs, still, the string will have to be parsed... – Trevor Apr 03 '19 at 20:02
  • @dbc thanks, but that won't help me either, due to the limitation mentioned – Tobias Brohl Apr 03 '19 at 20:03
  • @Nikolaus Yes it can contain curly brackets and any other character, so it wont work that way – Tobias Brohl Apr 03 '19 at 20:06
  • @Çöđěxěŕ Tobias Brohl is OP. – Nikolaus Apr 03 '19 at 20:08
  • @Nikolaus a possibly dumb question: Whats meant by OP? – Tobias Brohl Apr 03 '19 at 20:10
  • Related unanswered question: [How to get detailed position information from JsonTextReader](https://stackoverflow.com/q/53108483). Maybe you could open an enhancement request on https://github.com/JamesNK/Newtonsoft.Json/issues asking to track the position in the underlying text reader? – dbc Apr 03 '19 at 20:10
  • @Nikolaus shoot, wrong tagged person hahah I meant @ dbc... – Trevor Apr 03 '19 at 20:10
  • 2
    @Tobias Brohl the meaning of OP in this context is 'Original Poster'. – Theodor Zoulias Apr 03 '19 at 23:09

2 Answers2

4

You could make use of the SupportMultipleContent property, for example:

var json = "{\"a\":\"fdfsd\",\"b\":5}ghresd";

var reader = new JsonTextReader(new StringReader(json));
reader.SupportMultipleContent = true;

//Read the first JSON fragment
reader.Read();

var serializer = new JsonSerializer();
var result = serializer.Deserialize(reader);

//Or if you have a class to deserialise into:
//var result = serializer.Deserialize<YourClassHere>(reader);

//Line position is where the reader got up to in the JSON string
var extraData = json.Substring(reader.LinePosition);
DavidG
  • 113,891
  • 12
  • 217
  • 223
2

This piece of code might not work as expected if your json has multiple lines:

var extraData = json.Substring(reader.LinePosition);

You might need to consider adding additional check:

if(reader.LineNumber != 1)
  throw new NotSupportedException("Multiline JSON objects are not supported.");

Or you can take that value from private field using Reflection:

var charPosition = (int)reader.GetType().GetField("_charPos", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(reader);

JsonTextReader source code