Baraphor Baraphor - 3 months ago 25
JSON Question

Google Play Developer Api and JsonConvert.DeserializeObject

I am trying to deserialize an AchievementConfigurations: list REST Response from here https://developers.google.com/games/services/publishing/api/achievementConfigurations/list.

The problem is that this line only fills out the top level object and the List remains empty. No error messages are throw which makes this difficult to track down what is going on. I used a website to generate the json structured classes and after that I removed the duplicates which where unnecessary.

The response looks like this, I have removed the achievementConfiguration resource because it is really long but it can be found here https://developers.google.com/games/services/publishing/api/achievementConfigurations#resource

{
"kind": "gamesConfiguration#achievementConfigurationListResponse",
"nextPageToken": string,
"items": [
achievementConfigurations Resource
]
}


I have a series of classes I have created mirroring the data starting with the AchievementConfigurationListResponse class

public class AchievementConfigurationListResponse
{
public string kind = "gamesConfiguration#achievementConfigurationListResponse";
public string nextPageToken = "";

List<AchievementConfigurationResource> items = new List<AchievementConfigurationResource>();
}


Next up is the AchievementConfigurationResource which is an item in the list, it has several nested objects

public class AchievementConfigurationResource
{
public static string[] types = new string[] { "STANDARD", "INCREMENTAL" };
public static string[] states = new string[] { "REVEALED", "HIDDEN", "UNLOCKED" };

public string kind = "gamesConfiguration#achievementConfiguration";
public string token = "";
public string id = "";
public string achievementType = types[0];
public string initialState = states[0];

public int? stepsToUnlock;

public AchievementConfigurationDetail draft = new AchievementDataResource();
public AchievementConfigurationDetail published = new AchievementDataResource();
}


Those nested object are of this type of AchievementConfigurationDetail

public class AchievementConfigurationDetail
{
public string kind = "gamesConfiguration#achievementConfigurationDetail";
public LocalizedStringBundle name = new LocalizedStringBundle();
public LocalizedStringBundle description = new LocalizedStringBundle();
public int pointValue = 5;
public string iconUrl = "";
public int sortRank = 1;
}


Which contains several LocalizedStringBundles

public class LocalizedStringBundle
{
public string kind = "gamesConfiguration#localizedStringBundle";
public List<Translation> translations = new List<Translation>();

public class Translation
{
public string kind = "gamesConfiguration#localizedString";
public string locale = "en-US";
public string value = "";
}
}


I call this on the json with the following line:

AchievementConfigurationListResponse res = JsonConvert.DeserializeObject<AchievementConfigurationListResponse>(content);


Here is a copy of the response, sensitive data removed but the keys and structure are all intact. This one only contains a single record because the full file is something like 5000 lines long.

{
"kind": "gamesConfiguration#achievementConfigurationListResponse",
"items": [
{
"kind": "gamesConfiguration#achievementConfiguration",
"token": "Unique Token",
"id": "Unique ID",
"achievementType": "STANDARD",
"initialState": "REVEALED",
"draft": {
"kind": "gamesConfiguration#achievementConfigurationDetail",
"name": {
"kind": "gamesConfiguration#localizedStringBundle",
"translations": [
{
"kind": "gamesConfiguration#localizedString",
"locale": "en-US",
"value": "Name"
}
]
},
"description": {
"kind": "gamesConfiguration#localizedStringBundle",
"translations": [
{
"kind": "gamesConfiguration#localizedString",
"locale": "en-US",
"value": "Description"
}
]
},
"pointValue": 5,
"iconUrl": "Icon url",
"sortRank": 1
},
"published": {
"kind": "gamesConfiguration#achievementConfigurationDetail",
"name": {
"kind": "gamesConfiguration#localizedStringBundle",
"translations": [
{
"kind": "gamesConfiguration#localizedString",
"locale": "en-US",
"value": "Name"
}
]
},
"description": {
"kind": "gamesConfiguration#localizedStringBundle",
"translations": [
{
"kind": "gamesConfiguration#localizedString",
"locale": "en-US",
"value": "Description"
}
]
},
"pointValue": 5,
"iconUrl": "Icon url",
"sortRank": 1
}
}
]
}

dbc dbc
Answer

Json.NET does not serialize private members by default. Thus you need to make AchievementConfigurationListResponse.items be public:

public List<AchievementConfigurationResource> items = new List<AchievementConfigurationResource>();

Alternatively, mark it with [JsonProperty] which enables serialization of private members:

[JsonProperty]
List<AchievementConfigurationResource> items = new List<AchievementConfigurationResource>();