If you mark your class with [JsonObject(MemberSerialization.Fields)]
, that will get you most of the way there. This attribute tells Json.Net that you want it to serialize all fields in a class, regardless of access modifiers, but not properties.
However, if you have any auto properties in your class (i.e. those declared with { get; set; }
) then this attribute will cause the compiler-generated backing fields to be serialized as well, which you may not want. To suppress those, you will need to use a custom IContractResolver
. You can create one by inheriting from the DefaultContractResolver
and overriding the CreateProperty
method. In that method, check whether the class has the [JsonObject(MemberSerialization.Fields)]
attribute applied, and if so, check whether the member is a compiler-generated field. If it is, then set it to be ignored.
class CustomResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty prop = base.CreateProperty(member, memberSerialization);
JsonObjectAttribute attr = prop.DeclaringType.GetCustomAttribute<JsonObjectAttribute>();
if (attr != null && attr.MemberSerialization == MemberSerialization.Fields &&
member.GetCustomAttribute<CompilerGeneratedAttribute>() != null)
{
prop.Ignored = true;
}
return prop;
}
}
To use the resolver, you need to pass it to the SerializeObject
method via the JsonSerializerSettings
:
var settings = new JsonSerializerSettings
{
ContractResolver = new CustomResolver(),
Formatting = Formatting.Indented
};
string json = JsonConvert.SerializeObject(yourObject, settings);
Here is a proof of concept: https://dotnetfiddle.net/aNXWbn