4

I am working on a JSON driven project and I would like to provide the SessionManager object with a dynamic list of permissionst. While I can work with an array of key value pairs for permissions, I was wondering if I could remove the property names so that the key is the Permission value and the value is the IsAllowed value.

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}
        };
    }
}

When I generate JSON it outputs an array of permissions:

{
    "Permission": "CreateUsers",
    "IsAllowed": false
},

I would like to know how to override the serialization so that it uses the values instead of the property names.

{
    "CreateUsers": false
},
5
  • 2
    can you change the Permissions to instead be a Dictionary<string, bool>? Commented Mar 20, 2015 at 18:17
  • You have a good point. Commented Mar 20, 2015 at 18:37
  • doing so might make the serialization work as you want it to out of the box Commented Mar 20, 2015 at 18:40
  • @DLeh what if the keys are repeating ?? Commented Apr 13, 2020 at 19:03
  • 1
    Keys can't repeat in a dictionary. If you try to add a duplicate key to a dictionary, it throws an error Commented Apr 19, 2020 at 16:04

1 Answer 1

6

You could use the following custom converter:

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; }
    }
}

Usage:

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

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

Sample JSON:

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

It should work fine going the opposite way as well.

Example: https://dotnetfiddle.net/mfbnuk

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.