9

Is it possible to serialize static properties with JSON.NET without adding [JsonProperty] attribute to each property. Example class:

public class Settings
    {
        public static int IntSetting { get; set; }
        public static string StrSetting { get; set; }

        static Settings()
        {
            IntSetting = 5;
            StrSetting = "Test str";
        }
    }

Expected result:

{
  "IntSetting": 5,
  "StrSetting": "Test str"
}

Default behavior skips static properties:

var x = JsonConvert.SerializeObject(new Settings(), Formatting.Indented);
2

2 Answers 2

12

You can do this with a custom contract resolver. Specifically you need to subclass DefaultContractResolver and override the GetSerializableMembers function:

public class StaticPropertyContractResolver : DefaultContractResolver
{
    protected override List<MemberInfo> GetSerializableMembers(Type objectType)
    {
        var baseMembers = base.GetSerializableMembers(objectType);

        PropertyInfo[] staticMembers = 
            objectType.GetProperties(BindingFlags.Static | BindingFlags.Public);

        baseMembers.AddRange(staticMembers);

        return baseMembers;
    }
}

Here all we're doing is calling the base implementation of GetSerializableMembers, then adding public static properties to our list of members to serialize.

To use it you can create a new JsonSerializerSettings object and set the ContractResolver to an instance of the StaticPropertyContractResolver:

var serializerSettings = new JsonSerializerSettings();

serializerSettings.ContractResolver = new StaticPropertyContractResolver();

Now, pass those settings to JsonConvert.SerializeObject and everything should work:

string json = JsonConvert.SerializeObject(new Settings(), serializerSettings);

Output:

{
  "IntSetting": 5,
  "StrSetting": "Test str"
}

Example: https://dotnetfiddle.net/pswTJW

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

Comments

1

A more complicated way to solve this:

Solution 1:

public class Settings
{
    int intsetting { get; set; } /*= 0;*/ // commented only allowed in C# 6+
    string strsetting { get; set; } /*= "";*/

    public int IntSetting { get { return intsetting; } set { intsetting = value; } }
    public string StrSetting { get { return strsetting; } set { strsetting = value; } }

    static Settings()
    {
        IntSetting = 5;
        StrSetting = "Test str";
    }
}

Solution 2: (less complicated)

public class Settings
{
    [JsonProperty]
    public static int IntSetting { get; set; }

    [JsonProperty]
    public static string StrSetting { get; set; }

    static Settings()
    {
        IntSetting = 5;
        StrSetting = "Test str";
    }
}

Adding the [JsonProperty] to all variables would be the easyest way of solving this, but when you don't want to use it Solution 1 would fit best for you.

1 Comment

I was thinking there is a way to implement/override default JsonConverter behavior like recommended here: stackoverflow.com/questions/24336597/…. But I guess it's not a trivial solution.

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.