我有一个具有自定义的类,如下所示JsonConverter:
[JsonConverter(typeof(TheShapeSerializer))]
public class TheShape : IShape {
//....
}
Run Code Online (Sandbox Code Playgroud)
我不能改变班级。自定义序列化器的工作方式不适合我的需求。
有没有一种方法可以使用默认的序列化程序而不是TheShapeSerializer来序列化TheShape的实例?
同样,是否有一种方法可以让多个转换器根据给定条件在串行化时间选择?
选择JsonConverters的顺序记录如下:
使用JsonConverter的优先级是成员属性,然后是类属性,最后是传递给JsonSerializer的所有转换器。
因此,你不能禁用JsonConverter通过应用JsonConverterAttribute使用JsonSerializerSettings.Converters。相反,您有以下选择。
首先,如果您TheShape直接通过您控制的某种类型来引用您,则可以NoConverter从此答案中抓取到有选择地使用默认JSON转换器,然后使用JsonConverterAttribute或将其应用于引用成员JsonPropertyAttribute.ItemConverterType,例如,如下所示:
public class ShapeContainer
{
[JsonConverter(typeof(NoConverter))]
public TheShape Shape { get; set; }
[JsonProperty(ItemConverterType = typeof(NoConverter))]
public List<TheShape> Shapes { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在NoConverter将取代TheShapeSerializer应用它的属性,并导致Json.NET退回到默认序列化。
其次,如果,你不能成员属性添加到类型TheShape时,你可以创建一个自定义的合同解析器,它覆盖DefaultContractResolver.ResolveContractConverter和回报null的TheShape。首先定义以下合同解析器:
public class ConverterDisablingContractResolver : DefaultContractResolver
{
readonly HashSet<Type> types;
public ConverterDisablingContractResolver(IEnumerable<Type> types)
{
if (types == null)
throw new ArgumentNullException();
this.types = new HashSet<Type>(types);
}
bool ContainsType(Type type)
{
return types.Contains(type);
}
protected override JsonConverter ResolveContractConverter(Type objectType)
{
// This could be enhanced to deal with inheritance. I.e. if TBase is in types and has a converter then
// its converter should not be used for TDerived -- but if TDerived has its own converter then it should still be
// used, so simply returning null for TDerived would be wrong.
if (types.Contains(objectType))
return null;
return base.ResolveContractConverter(objectType);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,定义一个静态成员某处如下,供描述的性能的原因在这里:
static IContractResolver shapeResolver = new ConverterDisablingContractResolver(new[] { typeof(TheShape) });
Run Code Online (Sandbox Code Playgroud)
并序列化如下:
var settings = new JsonSerializerSettings
{
ContractResolver = shapeResolver,
};
var json = JsonConvert.SerializeObject(root, settings);
Run Code Online (Sandbox Code Playgroud)
演示小提琴在这里显示了两种选择。
同样,是否有一种方法可以让多个转换器根据给定条件在串行化时间选择?
显然,您可以JsonSerializerSettings.Converters根据运行时条件向其中添加不同的转换器。但是,如果你想运行转换器,以取代静态应用转换器,则需要使用适当的设置你的类型,例如,OverridableJsonConverterDecorator从这个回答到不使用定制IsoDateTimeConverter为什么Json.net?。
| 归档时间: |
|
| 查看次数: |
627 次 |
| 最近记录: |