Get Value from Jtoken That May Not Exist (Best Practices)

Get value from JToken that may not exist (best practices)

This is pretty much what the generic method Value() is for. You get exactly the behavior you want if you combine it with nullable value types and the ?? operator:

width = jToken.Value<double?>("width") ?? 100;

JSON.NET JToken Keys Are Case Sensitive?

You can cast JToken to JObject and do this:

string ver = ((JObject)token).GetValue("version", StringComparison.OrdinalIgnoreCase)?.Value<string>();

How to get a value from JToken at two levels deep in CSharp

You can achieve it with JObject, just like this:

var jObject = JObject.Parse(jsonstring);
var lastName = jObject["person"]["lastName"].Value<string>();

Json.NET get nested jToken value

You can use SelectToken() to select a token from deep within the LINQ-to-JSON hierarchy for deserialization. In two lines:

var token = jObj.SelectToken("response.docs");
var su = token == null ? null : token.ToObject<Solr_User []>();

Or in one line, by conditionally deserializing a null JToken when the selected token is missing:

var su = (jObj.SelectToken("response.docs") ?? JValue.CreateNull()).ToObject<Solr_User []>();

Sample fiddle.

In c# 6 or later it's even easier to deserialize a nested token in one line using the null conditional operator:

var su = jObj.SelectToken("response.docs")?.ToObject<Solr_User []>();

Or even

var su = jObj?["response"]?["docs"]?.ToObject<Solr_User []>();

Note that SelectTokens() is slightly more forgiving than the JToken index operator, as SelectTokens() will return null for a query of the wrong type (e.g. if the value of "response" were a string literal not a nested object) while the index operator will throw an exception.

Get value from JArray item with has inconsistent values

If the problem with the JSON is consistently that it is missing the value, you could insert, say, an empty string:

Dim json As String = "[{""bathrooms"": """"}, {""bathrooms"": }, {""bathrooms"": 2},{""bathrooms"": ""1""}]"
Dim re = New Text.RegularExpressions.Regex(":\s*}")
Dim json2 = re.Replace(json, ": """"}")

Console.WriteLine(json2)

Outputs:

[{"bathrooms": ""}, {"bathrooms": ""}, {"bathrooms": 2},{"bathrooms": "1"}]

which is valid JSON.

Then you could check if the value can be parsed as an integer:

Dim json As String = "[{""bathrooms"": """"}, {""bathrooms"": """"}, {""bathrooms"": 2},{""bathrooms"": ""1""}]"

Dim re = New Text.RegularExpressions.Regex(":\s*}")
json = re.Replace(json, ": """"}")

Dim nBathrooms As Integer
Dim jsonArray As Newtonsoft.Json.Linq.JArray = JArray.Parse(json)

For Each item In jsonArray
Dim q = item("bathrooms")
If q IsNot Nothing AndAlso Integer.TryParse(q.Value(Of Object).ToString(), nBathrooms) Then
Console.WriteLine(nBathrooms)
Else
Console.WriteLine("Not specified.")
End If

Next

Get value of any json by defining a key pattern at runtime

Use SelectToken and modify your pattern to be a JSONPath (which is just adding a "$" to the start).

string pattern = "$.data.value";
string json = "{\"request\": {\"method\": \"get\", \"key\": \"test\"}, \"code\": 0, \"type\": \"call\", \"data\": {\"value\": 14.0}}";
int data = JToken.Parse(json).SelectToken(pattern).Value<int>();
Console.WriteLine(data); // print "14"

Note that you can put <string> as the generic argument as well, even though the JSON value is a Number.



Related Topics



Leave a reply



Submit