我有一个无法更改的类:
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 而不是原始对象。