无论如何,要让JsonConvert.SerializeObject忽略属性上的JsonConverter属性?



我有一个无法更改的类:

public enum MyEnum {
Item1 = 0,
Item2 = 1
}
public class foo {
[JsonConverter(typeof(StringEnumConverter))]
public MyEnum EnumTypes {get; set; }
}

在某行的某个地方,JsonConvert.SerializeObject序列化对象,并且由于JsonConverter属性,它会吐出foo.EnumTypes的枚举值的名称而不是数字。

有没有办法让JsonConvert.SerializeObject忽略EnumTypes属性上的属性?

这是可能的,但这个过程有点复杂。

基本思想是创建自定义ContractResolver并重写其CreateProperty方法。 像这样:

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

您还需要实际实例化此类并将其传递到序列化程序/反序列化程序中。 它的外观取决于您如何进行序列化,因此我不能保证如何使用它的相关示例。

如果您只是使用静态SerializeObject方法:

JsonConvert.SerializeObject( valueToSerialize, new SerializerSettings { ContractResolver = new MyContractResolver() } );

之前的评论看起来很有希望,但由于某种原因它对我不起作用。我修改了接受的答案以满足我的需求。这是代码,如果有人需要它

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

Kyle的回答是一个很好的起点。在这个具体的简单示例中,它工作正常。但对我来说,它对嵌套属性不起作用,至少在 newtonsoft.json v12.0.3 中是这样。看看我发现的 DefaultContract Resolver 中还可以覆盖的内容

public virtual JsonContract ResolveContract(Type type);

它适用于嵌套属性:

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

和示例用法:

JsonConvert.SerializeObject(
myObject,
new SerializerSettings
{
ContractResolver = new NumericEnumContractResolver()
});

你可以使用 JsonIgnore 属性

public class Object
{
public string Key { get; set; }
[JsonIgnore]
public string Value { get; set; }
}

我是一个简单的人,我会创建单独的 DTO,将数据复制到该对象中并序列化此 DTO 而不是原始对象。

最新更新