JamesNK / Newtonsoft.Json

Json.NET is a popular high-performance JSON framework for .NET
https://www.newtonsoft.com/json
MIT License
10.73k stars 3.25k forks source link

JToken failing to return after successfully parsing #2849

Closed dayadam closed 1 year ago

dayadam commented 1 year ago

Source/destination types

JToken

Source/destination JSON

{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#servicePrincipals",
  "value": [
    {
      "accountEnabled": true,
      "addIns": [],
      "alternativeNames": [],
      "appDescription": null,
      "appDisplayName": "Microsoft Azure CLI",
      "appId": "04b07795-8ddb-461a-bbee-02f9e1bf7b46",
      "appRoles": [],
      "tokenEncryptionKeyId": null,
      "verifiedPublisher": {
        "addedDateTime": null,
        "displayName": null,
        "verifiedPublisherId": null
      }
    }
  ]
}

Expected behavior

To return JToken

Actual behavior

JToken successfully parses this JSON, but then an exception is throw when I try to return it in the method.

Newtonsoft.Json.JsonReaderException: Error reading JToken from JsonReader. Path '', line 0, position 0.

I noticed if I put it in a try / catch block and try to return and parse in the same line, in the catch block my string has been manipulated to an empty string "", which apparently also causes this error.

It also works with this near identical JSON

{
  "odata.metadata": "https://graph.windows.net/72f988bf-86f1-41af-91ab-2d7cd011db47/$metadata#directoryObjects",
  "value": [
    {
      "accountEnabled": true,
      "addIns": [],
      "alternativeNames": [],
      "appDisplayName": "Azure Monitor System",
      "appId": "11c174dc-1945-4a9a-a36b-c79a0f246b9b",
      "appRoleAssignmentRequired": false,
      "appRoles": [],
      "applicationTemplateId": null,
      "deletionTimestamp": null,
      "displayName": "Windows Azure Application Insights",
      "errorUrl": null,
      "homepage": null
    }
  ]
}

It's not the "@"

Steps to reproduce


            JToken token = null;

            token = JToken.Parse(output);

            return token;
elgonzo commented 1 year ago

Not reproducible.

The json data in your issue report does NOT produce the error you observed. Proof: https://dotnetfiddle.net/iQq17G

I suspect your actual output string your code is passing to JToken.Parse is either invalid/corrupted json or an empty (or white-space only) string and not the json from your issue report as you seem to believe.

I noticed if I put it in a try / catch block and try to return and parse in the same line, in the catch block my string has been manipulated to an empty string "", which apparently also causes this error.

There you go... so find out what part of your code sets output to an empty string (perhaps you have a race condition / multithreading bug???). Since the method parameter of JToken.Parse is not a ref string, it can't be the culprit, because it can't set the output variable to an empty string.

dayadam commented 1 year ago

@elgonzo you're right. It was sort of a multithreading misunderstanding.