Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I get a JsonReaderException with this code?

Tags:

c#

json.net

I've got this code to try to open a .json file and read it:

[Route("{unit}/{begindate}")]
public string Get(string unit, string begindate)
{
    string _unit = unit;
    string _begindate = String.Format("{0}01", PlatypusWebReportsConstsAndUtils.HyphenizeYYYYMM(begindate));           
    string appDataFolder = HttpContext.Current.Server.MapPath("~/App_Data/");
    // semi-hardcoded file name for now
    string jsonFilename = string.Format("PoisonToe_{0}_{1}.json", _unit, _begindate);
    string fullPath = Path.Combine(appDataFolder, jsonFilename);
    JObject platypusComplianceJson = JObject.Parse(File.ReadAllText(fullPath));
    . . .

On the last line, I get:

Newtonsoft.Json.JsonReaderException was unhandled by user code HResult=-2146233088 Message=Error reading JObject from JsonReader. Current JsonReader item is not an object:

Based on what I read here, I thought this would be the way to do it. What am I doing wrong?

like image 818
B. Clay Shannon-B. Crow Raven Avatar asked Jan 01 '16 00:01

B. Clay Shannon-B. Crow Raven


1 Answers

It's difficult to give a better answer without the information requested in comments, but this means, as it suggests, that the current token isn't the start of an object.

Just to be clear, we're talking about "object" in the JSON vocabulary, and not in the C#/OOP vocabulary sense.

It sounds like what's going on here is something like the non-JSON bool.Parse("1"). Yes, "1" is valid input to a parse method (int.Parse, for instance), but this is the wrong method.

The simple trick (warning: Band-Aid fix) is to switch to JToken.Parse. JToken is a polymorphic parent of JObject, JArray, JValue, and the lot, so its parse is able to handle a lot more types of unstructured input.

Before you do that, as I'm sure you know, you should of course double-check your contracts and the file, to see which is wrong. There's certainly no good in successfully parsing a JArray that you then use as a JObject.

For good measure, a few file texts that would cause this error are:

  • (empty file)
  • [{ "test": "val" }] (array)
  • "test" (string)
  • null

These should all be valid inputs to JToken.Parse, I believe, but they'd all give this error on JObject.Parse, because they aren't objects. You need something like:

  • { "test": "val" }
  • { "test": { "val": 2 } }

Or something to that effect.


Back on my OOP point, a JObject isn't the elementary base type of everything in JSON.net, but JToken is. So even though you could say,

object i = new int[0];

in C#, you can't say,

JObject i = JObject.Parse("[0, 0, 0]");

in JSON.net.

like image 187
Matthew Haugen Avatar answered Oct 19 '22 03:10

Matthew Haugen