带有嵌套对象的Json,每个都有不同的名称

时间:2019-10-31 21:06:35

标签: c# .net-core

我有一个来自端点的json对象。

{
"user_info": {
    "myapp1": {
      "roles": [
        "requestor"
      ]
    },
    "myapp2": {
      "roles": [
        "requests-edit",
        "requests-view"
      ]
    },
    "account": {
      "roles": [
        "manage-account",
        "manage-account-links",
        "view-profile"
      ]
    }
  }
}

基于这种结构,很明显有两个强类型对象。 user_inforoles。但是,应用(myapp1, myapp2, account)不在数组中,它们是“动态”或“匿名”对象。

使用已知应用名称获取角色的推荐方法是什么?

EG,一些伪代码。

// 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.

2 个答案:

答案 0 :(得分:3)

嘿,我建议创建2个反序列化类

    public class UserInfo
    {
        [JsonProperty("user_info")]
        public Dictionary<string, Account> Users { get; set; }
    }

    public class Account
    {
        [JsonProperty("roles")]
        public List<string> Roles { get; set; }
    }

反序列化可能看起来像这样

        var info = JsonConvert.DeserializeObject<UserInfo>(jsonString);
        var allRoles = info.Users.SelectMany(x => x.Value.Roles);

示例使用Newtonsoft软件包

希望这会有所帮助。

答案 1 :(得分:2)

类似于@OwnBlood的建议,您可以使用Newtonsoft.Json框架制作两个类:

public class Application
{
    [JsonProperty("roles")]
    public IEnumerable<string> Roles { get; set; }
}

public class User
{
    [JsonProperty("user_info")]
    public IDictionary<string, Application> UserInfo { get; set; }
}

然后您可以使用 JsonConvert.DeserializeObject()方法反序列化:

var deserializedJson = JsonConvert.DeserializeObject<User>(jsonString);

您可以创建一种使用LINQ从特定应用程序名称中过滤掉角色的方法:

private static IEnumerable<string> GetUserApplicationRoles(string applicationName, User data) => 
    data.UserInfo
        .TryGetValue(applicationName, out var value) ?
            value.Roles : 
            Enumerable.Empty<string>();

说明:

  • 由于UserInfoIDictionary<string, Application>,因此我们可以使用TryGetValue访问特定的applicationName。这允许O(1)访问。
  • 然后,我们可以简单地返回IEnumerable<string>角色,或者返回一个空集合,在这种情况下为Enumerable.Empty<string>

dotnetfiddle.net上找到的工作演示