2

Some background to my question: I'm looking to deserialize some horrid json within Json.net. This json object is created by ArcGIS Server, and sends a 'results' object which is formatted thusly:

{ "results" : [ { "layerId" : 10, "layerName" : "Polling Districts", "value" : "MyWard", "displayFieldName" : "Ward", "attributes" : { "OBJECTID" : "61", "Ward" : "MyWard", "Polling Station" : "Childrens Resources Centre", "Polling District" : "E", "Constituency" : "South", "Shape" : "Polygon" } } ] }

Now the problem is the attributes object:

{ "OBJECTID" : "61", "Ward" : "MyWard", "Polling Station" : "Childrens Resources Centre", "Polling District" : "E", "Constituency" : "South", "Shape" : "Polygon" }

...which has whitespace in some identifiers; it's being generated by the 'pretty' field alias, and not the data table name. I'm able to use the linq selectToken to get all other fields, but I'm looking for "Polling Station" in particular.

I've tried quite a few variants of the query:

string pollingStation = (string)jObj.SelectToken("results[0].attributes[Polling Station]"); // Unexpected character while parsing path indexer: P  
string pollingStation = (string)jObj.SelectToken("results[0].attributes[\"Polling Station\"]"); //Unexpected character while parsing path indexer: "  
string pollingStation = (string)jObj.SelectToken("results[0].attributes.\"Polling Station\""); // No error, pollingStation is null  
string pollingStation = (string)jObj.SelectToken("results[0].attributes.Constituency"); // No error, pollingStation is South (correct)

I've googled, searched the json.net help & read quite a few questions already posted here - none of which seem to deal with this particular question. Maybe I'm just being dense. You may also be able to tell I'm not proficient in c#, or Linq, and this is the first time I've used Json.net so I have probably made some schoolboy errors. Any suggestions welcome!

Stoat
  • 23
  • 1
  • 3
  • This has nothing to do with LINQ – SLaks Jul 20 '11 at 14:13
  • Do you *have* to use SelectToken? Can you just use the indexer to get at individual values instead? That's what I've always done. – Jon Skeet Jul 20 '11 at 14:13
  • SLaks: sorry - I was under the impression SelectToken was in the Newtonsoft.Json.Linq namespace. It isn't. – Stoat Jul 20 '11 at 14:16
  • Jon: No, I don't have to use SelectToken - I thought it'd be the simplest way to get at specific elements without deserializing the whole thing into an object. Could you elaborate on how I'd go about doing it the other way? Where in the Json.net documentation should I be looking? – Stoat Jul 20 '11 at 14:27

1 Answers1

2

Reading the JPath.ParseMain code in JPath.cs what works is

var json = @"{ ""results"" : [ { ""layerId"" : 10, ""layerName"" : ""Polling Districts"", ""value"" : ""MyWard"", ""displayFieldName"" : ""Ward"", ""attributes"" : { ""OBJECTID"" : ""61"", ""Ward"" : ""MyWard"", ""Polling Station"" : ""Childrens Resources Centre"", ""Polling District"" : ""E"", ""Constituency"" : ""South"", ""Shape"" : ""Polygon"" } } ] }";
var jObj = JObject.Parse(json);
var pollingStation = (string)jObj.SelectToken("results[0].attributes.['Polling Station']");

Remark: in pre-2013 JSon.Net it worked without any form of escaping :

var pollingStation = (string)jObj.SelectToken("results[0].attributes.Polling Station");
Julien Roncaglia
  • 17,397
  • 4
  • 57
  • 75
  • Nice. I didn't even consider it'd 'just work' without having to be quoted, bracketed, or otherwise escaped. Thanks! – Stoat Jul 20 '11 at 15:16
  • In fact reading the code, nothing is escapable. It mean that some correct json attributes names like "x[.3" can't be accessed via this API (attributes names are arbitrary unicode strings in json). – Julien Roncaglia Jul 21 '11 at 08:50
  • Four years after this answer was originally posted here, I can't get this to work in Newtonsoft.Json 7.0.0. I get an error that says that there is an "invalid character". In my case, this consistently happens with whitespace. – Vivian River Aug 31 '15 at 18:47
  • 1
    json.net changed their format in 2013 it's now `attributes.['Polling Station']` i'll update my answer. – Julien Roncaglia Aug 31 '15 at 19:10
  • Thanks for your help, @Julien. I'm going to see about getting this added to the official documentation. As of now, I don't see anything about it there. – Vivian River Aug 31 '15 at 20:19