Reputation: 61606
I have a class that I cannot change:
public enum MyEnum {
Item1 = 0,
Item2 = 1
}
public class foo {
[JsonConverter(typeof(StringEnumConverter))]
public MyEnum EnumTypes {get; set; }
}
Somewhere down the line JsonConvert.SerializeObject
serializes the object and because of the JsonConverter
attribute, it spits out name of the enum value for the foo.EnumTypes
rather than the number.
Is there anyway to get JsonConvert.SerializeObject
to ignore the attribute on the EnumTypes
property?
Upvotes: 13
Views: 8607
Reputation: 11
You could use JsonIgnore attribute
public class Object
{
public string Key { get; set; }
[JsonIgnore]
public string Value { get; set; }
}
Upvotes: 1
Reputation: 34967
I'm a simple man and I would create separate DTO, copy the data into that object and serialise this DTO and not the original object.
Upvotes: 1
Reputation: 814
The previous comment looked really promising, but for some reason it didn't work for me. I modified accepted answer to fit my needs. Here is the code if anyone ever needs it
public class IgnoreConvertersContractResolver : DefaultContractResolver
{
private readonly Type[] _typesToIgnore;
public IgnoreConvertersContractResolver(params Type[] typesToIgnore)
{
_typesToIgnore = typesToIgnore;
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
var attributes = property.AttributeProvider.GetAttributes(false);
foreach (var attribute in attributes)
{
if (attribute is JsonConverterAttribute converterAttribute
&& _typesToIgnore.Contains(converterAttribute.ConverterType))
{
property.Converter = null;
break;
}
}
return property;
}
Upvotes: 2
Reputation: 6627
Kyle's answer is a great starting point. It works fine in this concrete simple example from question. But for me it didn't work recursively for the nested properties, at least with newtonsoft.json v12.0.3. Looking at what else can be overwritten in DefaultContractResolver I've found
public virtual JsonContract ResolveContract(Type type);
and it worked fine for nested properties:
internal sealed class NumericEnumContractResolver : DefaultContractResolver
{
private Type _stringEnumConverterType = typeof(StringEnumConverter);
protected override JsonConverter ResolveContractConverter(Type objectType)
{
var converter = base.ResolveContractConverter(objectType);
if ((converter != null) &&
(converter.GetType() == _stringEnumConverterType))
{
converter = null;
}
return converter;
}
}
and sample usage:
JsonConvert.SerializeObject(
myObject,
new SerializerSettings
{
ContractResolver = new NumericEnumContractResolver()
});
Upvotes: 2
Reputation: 6684
This is possible, but the process is a tad involved.
The basic idea is to create a custom ContractResolver
and override its CreateProperty
method. Something like so:
internal sealed class MyContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty( MemberInfo member, MemberSerialization memberSerialization )
{
var property = base.CreateProperty( member, memberSerialization );
if( member.DeclaringType == typeof( foo ) && property.PropertyType == typeof( MyEnum ) )
{
property.Converter = null;
}
return property;
}
}
You'll also need to actually instantiate this class and pass it into your serializer/deserializer. What that looks like depends on exactly how you're doing the serialization, so I can't guarantee a relevant example of how to use it.
If you're just using the static SerializeObject
method:
JsonConvert.SerializeObject( valueToSerialize, new SerializerSettings { ContractResolver = new MyContractResolver() } );
Upvotes: 12