Reputation: 2103
I have a json object that is coming from an endpoint.
{
"user_info": {
"myapp1": {
"roles": [
"requestor"
]
},
"myapp2": {
"roles": [
"requests-edit",
"requests-view"
]
},
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
}
}
Based on this structure its pretty clear that there are two strongly typed objects. user_info
and roles
. However, the apps (myapp1, myapp2, account)
are not in an array, they are "dynamic" or "anonymous" objects.
What is the recommended way to get the roles with a known app name?
EG, some pseudo code.
// returns the sub objects as a dictionary of <string, Roles>;
var anonjson = JsonAnon.DeserializeOnProperty<string, Roles>("user_info");
var roles = anonjson.Where(x => x.Key.Value == "myapp2").FirstOrDefault();
// i forget what dictionaries use to get by key I put x.Key, this could be invalid.
Upvotes: 1
Views: 240
Reputation: 26315
Similar to what @OwnBlood suggested, you can make two classes using the Newtonsoft.Json framework:
public class Application
{
[JsonProperty("roles")]
public IEnumerable<string> Roles { get; set; }
}
public class User
{
[JsonProperty("user_info")]
public IDictionary<string, Application> UserInfo { get; set; }
}
Then you can deserialize with the JsonConvert.DeserializeObject() method:
var deserializedJson = JsonConvert.DeserializeObject<User>(jsonString);
And you can create a method that filters out the roles from a specific application name using LINQ:
private static IEnumerable<string> GetUserApplicationRoles(string applicationName, User data) =>
data.UserInfo
.TryGetValue(applicationName, out var value) ?
value.Roles :
Enumerable.Empty<string>();
Explanation:
UserInfo
is a IDictionary<string, Application>
, we can use TryGetValue
to access the specific applicationName
. This allows O(1) access. IEnumerable<string>
roles, or an empty collection, in this case Enumerable.Empty<string>
. Working demo found at dotnetfiddle.net
Upvotes: 2
Reputation: 197
Hey I suggest creating 2 classes for Deserialization
public class UserInfo
{
[JsonProperty("user_info")]
public Dictionary<string, Account> Users { get; set; }
}
public class Account
{
[JsonProperty("roles")]
public List<string> Roles { get; set; }
}
The deserialization could then look like this
var info = JsonConvert.DeserializeObject<UserInfo>(jsonString);
var allRoles = info.Users.SelectMany(x => x.Value.Roles);
The examle uses the Newtonsoft package
Hope this helps.
Upvotes: 3