claydiffrient
claydiffrient

Reputation: 1306

Parsing through JSON in JSON.NET with unknown property names

I have some JSON Data which looks like this:

{
   "response":{
   "_token":"StringValue",
   "code":"OK",
   "user":{
     "userid":"2630944",
     "firstname":"John",
     "lastname":"Doe",
     "reference":"999999999",
     "guid":"StringValue",
     "domainid":"99999",
     "username":"jdoe",
     "email":"[email protected]",
     "passwordquestion":"",
     "flags":"0",
     "lastlogindate":"2013-02-05T17:54:06.31Z",
     "creationdate":"2011-04-15T14:40:07.22Z",
     "version":"3753",
     "data":{
       "aliasname":{
         "$value":"John Doe"
       },
       "smsaddress":{
         "$value":"[email protected]"
       },
       "blti":{
         "hideemail":"false",
         "hidefullname":"false"
       },
       "notify":{
         "grades":{
            "$value":"0"
          },
          "messages":{
            "$value":"1"
          }
       },
       "beta_component_courseplanexpress_1":{
         "$value":"true"
       }
    }
  }
}

I am using C# with JSON.NET to parse through the data. I've been able to sucessfully get data using this algorithm:

User MyUser = new User();
JToken data = JObject.Parse(json);
MyUser.FirstName = (string) data.SelectToken("response.user.firstname");
//The same for all the other properties.

The problem is with the data field. This field is based on user preferences mostly and data is only inserted as it is used. The fields are all custom and developers can put in as many as they want without restrictions. Essentially, it's all free form data. Also as you notice they can be nested really far with data.

I've tried to run:

MyUser.Data = JsonConvert.DeserializeObject<List<JToken>>((string) data.SelectToken("response.user.data");

which doesn't work.

How would you go about converting it to be used in a C# object?

Upvotes: 15

Views: 25967

Answers (2)

Dan Saltmer
Dan Saltmer

Reputation: 2165

Json.NET can actually parse to a dynamic if that is useful to you. Which means you can do something like.

dynamic parsedObject = JsonConvert.DeserializeObject("{ test: \"text-value\" }");

parsedObject["test"]; // "text-value"
parsedObject.test; // "text-value"
parsedObject.notHere; // null

Edit: might be more suitable for you to iterate the values if you don't know what you are looking for though.

dynamic parsedObject = JsonConvert.DeserializeObject("{ test: { inner: \"text-value\" } }");
foreach (dynamic entry in parsedObject)
{
    string name = entry.Name; // "test"
    dynamic value = entry.Value; // { inner: "text-value" }
}

Upvotes: 19

carlosfigueira
carlosfigueira

Reputation: 87228

You can access it via the JToken / JArray / JObject methods. For example, this will list all of the keys under the data:

public class StackOverflow_14714085
{
    const string JSON = @"{
                          ""response"": {
                            ""_token"": ""StringValue"",
                            ""code"": ""OK"",
                            ""user"": {
                              ""userid"": ""2630944"",
                              ""firstname"": ""John"",
                              ""lastname"": ""Doe"",
                              ""reference"": ""999999999"",
                              ""guid"": ""StringValue"",
                              ""domainid"": ""99999"",
                              ""username"": ""jdoe"",
                              ""email"": ""[email protected]"",
                              ""passwordquestion"": """",
                              ""flags"": ""0"",
                              ""lastlogindate"": ""2013-02-05T17:54:06.31Z"",
                              ""creationdate"": ""2011-04-15T14:40:07.22Z"",
                              ""version"": ""3753"",
                              ""data"": {
                                ""aliasname"": {
                                  ""$value"": ""John Doe""
                                },
                                ""smsaddress"": {
                                  ""$value"": ""[email protected]""
                                },
                                ""blti"": {
                                  ""hideemail"": ""false"",
                                  ""hidefullname"": ""false""
                                },
                                ""notify"": {
                                  ""grades"": {
                                    ""$value"": ""0""
                                  },
                                  ""messages"": {
                                    ""$value"": ""1""
                                  }
                                },
                                ""beta_component_courseplanexpress_1"": {
                                  ""$value"": ""true""
                                }
                              }
                            }
                          }
                        }";

    public static void Test()
    {
        var jo = JObject.Parse(JSON);
        var data = (JObject)jo["response"]["user"]["data"];
        foreach (var item in data)
        {
            Console.WriteLine("{0}: {1}", item.Key, item.Value);
        }
    }
}

Upvotes: 21

Related Questions