49

I'm using Newtonsoft Json.net to parse the JSON string. I convert the string into the JObject. When access the value of the element by the key, I want to the comparison is case-insensitive. In the code below, I use "FROM" as the key. I want it returns string "1" at the line json["FROM"].ToString(). But it fails. Is it possible to make the code below work?

String ptString = "{from: 1, to: 3}";
var json = (JObject)JsonConvert.DeserializeObject(ptString);

String f = json["FROM"].ToString();
Jeffrey
  • 4,436
  • 9
  • 38
  • 54
  • 1
    Refer to [this answer](http://stackoverflow.com/a/2738375/578843) that this is wanted according the JSON-RPC spec (keys are case sensitive!). – Styxxy Aug 21 '12 at 13:30
  • Couldnt you create some logic with .toUpper or .toLower in one of the ends? – Ademar Aug 21 '12 at 15:36
  • 1
    You really should consider updating the accepted answer to the top voted one: https://stackoverflow.com/a/20475542/67824 – Ohad Schneider Oct 10 '18 at 13:42

2 Answers2

141

This should work:

var json = @"{UPPER: 'value'}";
var jObj = JObject.Parse(json);
var upper = jObj.GetValue("upper", StringComparison.OrdinalIgnoreCase)?.Value<string>();

Console.WriteLine(upper); // value
Gian Marco
  • 22,140
  • 8
  • 55
  • 44
15

c# allows you to use dictionaries with keys that are case insensitive, so a workaround I've used is to convert the JObject to a dictionary with StringComparer.CurrentCultureIgnoreCase set, like so:

JObject json = (JObject)JsonConvert.DeserializeObject(ptString);
Dictionary<string, object> d = new Dictionary<string, object>(json.ToObject<IDictionary<string, object>>(), StringComparer.CurrentCultureIgnoreCase);

String f = d["FROM"].ToString();
cecilphillip
  • 11,446
  • 4
  • 36
  • 40
ForeverWintr
  • 5,492
  • 2
  • 36
  • 65
  • 10
    The downside of this approach is that you lose the ability of getting anything below "level 1", meaning you cant get any nested property. –  Jul 13 '13 at 11:33
  • 1
    I don't see that so much of a downside. Unless you are not using an Azure API or auto generated Swagger JSON, there should be little to no issue with the depth. All of that is calculated and classes are created to handle the nesting in the correct order. This adds a slight amount of overhead depending on the object, but overall, I find this to be quite useful. In my case, the documentation that the Web Client was created from changed their property casing... again. Since they don't adhere to their own "contract," something like this prevents me having to go back and fix the code each time. – Anthony Mason Aug 26 '16 at 19:55
  • 1
    I'd suggest using this instead: var dictionary = new Dictionary(jo.ToObject>(), StringComparer.CurrentCultureIgnoreCase) as it allows the use of .ToObject on the returned value, unlike the answer. – Chris Peacock Jan 22 '19 at 18:27