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