我有一个无法更改的课程:
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;
}
凯尔的回答是一个很好的起点。在这个具体的简单例子中,它工作得很好。但对我来说,它无法递归地用于嵌套属性,至少在 newtonsoft.json v12.0.3 中是这样。查看我发现的 DefaultContractResolver 中还有哪些内容可以被覆盖
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()
});
我是一个简单的人,我会创建单独的 DTO,将数据复制到该对象中并序列化此 DTO 而不是原始对象。
您可以使用 JsonIgnore 属性
public class Object
{
public string Key { get; set; }
[JsonIgnore]
public string Value { get; set; }
}