C# JSON序列化使用值而非属性名称

4

我正在处理一个由JSON驱动的项目,并且想要为SessionManager对象提供一个动态权限列表。尽管我可以使用权限的键值对数组来工作,但我在思考是否可以去掉属性名称,让key成为Permission的值,而value则是IsAllowed的值。

public class SessionPermission
{
    public string Permission { get; set; }
    public bool IsAllowed { get; set; }
}


public class SessionManager
{
    public string UserName { get; set; }
    public string Password { get; set; }
    public List<SessionPermission> Permissions { get; set; }

    public void SetPermissions()

    {
        Permissions = new List<SessionPermission>
        {
            new SessionPermission {Permission = "CreateUsers", IsAllowed = false},
            new SessionPermission {Permission = "EditUsers", IsAllowed = false},
            new SessionPermission {Permission = "EditBlog", IsAllowed = true}
        };
    }
}

当我生成JSON时,它输出一个权限数组:
{
    "Permission": "CreateUsers",
    "IsAllowed": false
},

我想知道如何覆盖序列化,使其使用值而不是属性名称。
{
    "CreateUsers": false
},

2
你能否将“Permissions”更改为“Dictionary<string, bool>”? - DLeh
你说得很有道理。 - Pete
这样做可能会使序列化按照您的预期开箱即用。 - DLeh
@DLeh 如果键重复怎么办? - Rohit Kumar
1
字典中的键不能重复。如果您尝试向字典中添加重复的键,则会引发错误。 - DLeh
1个回答

6
您可以使用以下自定义转换器:
public class SessionPermissionConverter : JsonConverter
{
    public override object ReadJson(
        JsonReader reader,
        Type objectType,
        object existingValue,
        JsonSerializer serializer)
    {
        var obj = (JObject)JObject.ReadFrom(reader);


        JProperty property = obj.Properties().FirstOrDefault();

        return new SessionPermission
        {
            Permission = property.Name,
            IsAllowed = property.Value.Value<bool>()
        };
    }

    public override void WriteJson(
        JsonWriter writer,
        object value,
        JsonSerializer serializer)
    {
       SessionPermission permission = (SessionPermission)value;

       JObject obj = new JObject();

       obj[permission.Permission] = permission.IsAllowed;

       obj.WriteTo(writer);
    }

    public override bool CanConvert(Type t)
    {
        return typeof(SessionPermission).IsAssignableFrom(t);
    }

    public override bool CanRead
    {
        get { return true; }
    }
}

使用方法:

var manager = new SessionManager();
manager.SetPermissions();

string json = JsonConvert.SerializeObject(manager, new SessionPermissionConverter());

示例JSON:

{
  "UserName": null,
  "Password": null,
  "Permissions": [
    {
      "CreateUsers": false
    },
    {
      "EditUsers": false
    },
    {
      "EditBlog": true
    }
  ]
}

反过来也应该能正常工作。

示例:https://dotnetfiddle.net/mfbnuk


太棒了。这正是我在寻找的。感谢您的帮助。 - Pete
1
@Pete:没问题,很高兴能帮忙。 - Andrew Whitaker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接