2

I have a JSON structure like below to show the details of a specific candidate It can be either null or can contain some details like below

     "details": {
        "gender": {
          "id": 3,
          "props": {
            "name": "male"
          }
        }
    }

    or as null

    "details": {
        "gender": null
    }

To read the value of gender i tried

 string _gender = (string)result["details"]["gender"]["props"]["name"];  

This will works in non null cases . But if its null then this code returns an exception

So to check first is it null or not and if not null try to read the value, i tried below code

        string _gender = (string)result["details"]["gender"];
        if (!string.IsNullOrEmpty(_gender))
        {
            _gender = (string)result["details"]["gender"]["props"]["name"]; 
        }

But i am getting the exception that not possible to convert object to string. So how to read a JSON property with proper null handling \

Sebastian
  • 4,625
  • 17
  • 76
  • 145
  • 2
    Why not deserialize it to a type where gender is nullable ? – Felix D. Jan 15 '18 at 07:08
  • gender is just a property from a JArray . – Sebastian Jan 15 '18 at 07:09
  • You could still deserialize it. If you use [Json2C#](http://json2csharp.com/) with your complete json you could then make the type of `details` nullable and deserialize your json to an object e.g. `List`. Then fetch the details property for all instances. – Felix D. Jan 15 '18 at 07:12
  • the json is of dynamic in nature, So its hard to set all the nullable and non-nullable properties for the entire json parsing. This gender is just one of the property i am struggling to parse. And i am trying to find a olution to handle null in this way – Sebastian Jan 15 '18 at 07:13
  • 1
    Maybe just `if(result["details"]["gender"] != null)` ? Remember that `result["details"]["gender"]` is of type JToken, not string – Fabjan Jan 15 '18 at 07:17
  • 1
    Looks like a duplicate of [Json.NET get nested jToken value](https://stackoverflow.com/q/42290485/3744182). Agree? – dbc Jan 15 '18 at 07:22

2 Answers2

2

I strongly suggest you to deserialize the json as known type.

public class Props
{
    public string name { get; set; }
}

public class Gender
{
    public int id { get; set; }
    public Props props { get; set; }
}

public class Details
{
    public Gender gender { get; set; }
}

public class JsonObject
{
    public Details details { get; set; }
}

Then perform deserialization;

var jsonObject = JsonConvert.DeserializeObject<List<JsonObject>>(json);
foreach (var o in jsonObject)
{
    var genderName = o?.details?.gender?.props?.name;
}

In this way, you can handle the possible null values and get strongly typed object.

EDIT

Also, in your code, you are trying to convert an object to string and it is completely wrong. It seems that gender object is a complex type. So you can't convert it to string and you should modify your code like this;

object _gender = result["details"]["gender"];
if (_gender != null)
{
    string genderName = result["details"]["gender"]["props"]["name"].ToString();
}
lucky
  • 12,734
  • 4
  • 24
  • 46
  • sorry the json is of highly dynamic in nature, So its hard to set all the nullable and non-nullable properties on the entire json for parsing. This gender is just one of the property i am struggling to parse. And i am trying to find a solution to solve nullable JToken parsing basically – Sebastian Jan 15 '18 at 07:34
0

Keep in mind that jToken[xx..][yy..] is not a string, it is a JToken object, therefore we cannot explicitly cast it to string. If we want to convert it to string we'd have to call ToString() on it explicitly (which in terms calls JToken's overridden implementation of .ToString).

First we need to check that Jtoken has values for that we have method .HasValues. Later when we know for certain that there is a string in ["name"] property we can use either - explicit cast or .ToString() again

string _gender;
var genderToken = jToken["details"]["gender"];
if (genderToken.HasValues)
{
    _gender = genderToken["props"]["name"].ToString();
}
Fabjan
  • 13,506
  • 4
  • 25
  • 52