我正在try 从Newtonsoft.Json迁移到System.Text.Json,并且我正在try 找到一种方法来判断是否我的所有数据都已被"捕获"并且被正确映射(Re:PolyphismOptions),因为我已经使用了大量的泛型/抽象/接口类型.
有没有办法做到这一点:
-
确定它目前try 转换的类型?JsonTypeInfoResolver中的
GetTypeInfo()
似乎只返回它找到的"基本"类型. -
抛出某种异常或错误,IFF它发现一个问题?
提前谢谢您!
我正在try 从Newtonsoft.Json迁移到System.Text.Json,并且我正在try 找到一种方法来判断是否我的所有数据都已被"捕获"并且被正确映射(Re:PolyphismOptions),因为我已经使用了大量的泛型/抽象/接口类型.
有没有办法做到这一点:
确定它目前try 转换的类型?JsonTypeInfoResolver中的GetTypeInfo()
似乎只返回它找到的"基本"类型.
抛出某种异常或错误,IFF它发现一个问题?
提前谢谢您!
在构造已声明类型的约定时,我不知道有什么方法可以使实际类型被序列化.
但是,您可以强制System.Text.Json在序列化意外派生类型时自动引发异常.为此,您需要创建一个JsonTypeInfo
modifier,以自动将所有相关非密封类型的JsonPolymorphismOptions.UnknownDerivedTypeHandling
设置为FailSerialization
:
public static partial class JsonExtensions
{
public static Action<JsonTypeInfo> SetupUnknownDerivedTypeHandling(bool objectsOnly = false) =>
(typeInfo) =>
{
// Polymorphism using type discriminators is only supported for type hierarchies that use the default converters for objects, collections, and dictionary types.
if (typeInfo.Kind == JsonTypeInfoKind.None || typeInfo.Type.IsSealed || typeInfo.Type == typeof(object))
return;
if (objectsOnly && typeInfo.Kind != JsonTypeInfoKind.Object)
return;
// TODO: decide whether to fail serialization even for types marked with
// [JsonPolymorphic(UnknownDerivedTypeHandling = FallBackToBaseType or FallBackToNearestAncestor)]
if (typeInfo.PolymorphismOptions == null)
{
typeInfo.PolymorphismOptions = new() { DerivedTypes = { new(typeInfo.Type) } };
// TODO: decide whether to fail serialization even for types marked with
// [JsonPolymorphic(UnknownDerivedTypeHandling = FallBackToBaseType or FallBackToNearestAncestor)]
// If so, move the setting of UnknownDerivedTypeHandling out of this if statement.
typeInfo.PolymorphismOptions.UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FailSerialization;
};
};
}
然后设置选项,例如,如下所示:
var options = new JsonSerializerOptions()
{
// Configure either a DefaultJsonTypeInfoResolver or some JsonSerializerContext and add the required modifier:
TypeInfoResolver = new DefaultJsonTypeInfoResolver()
.WithAddedModifier(JsonExtensions.SetupUnknownDerivedTypeHandling()),
// Set other options as required.
};
备注:
因为System.Text.Json总是为声明为object
的引用序列化完整的具体类型,所以在这种情况下我不会抛出异常.
多态类型可以为JsonPolymorphicAttribute.UnknownDerivedTypeHandling
配置特定的行为,其中FailSerialization
是默认行为.来自docs家的:
JsonUnknownDerivedTypeHandling value |
Effect |
---|---|
FailSerialization | An object of undeclared runtime type will fail polymorphic serialization. The default. |
FallBackToBaseType | An object of undeclared runtime type will fall back to the serialization contract of the base type. |
FallBackToNearestAncestor | An object of undeclared runtime type will revert to the serialization contract of the nearest declared ancestor type. Certain interface hierarchies are not supported due to diamond ambiguity constraints. |
如果您的某些类型的静态配置行为不是FailSerialization
,而您想要覆盖它,则可以通过将该设置移到if (typeInfo.PolymorphismOptions == null)
判断之外来执行此操作.
就我个人而言,我不建议意外的集合或字典类型导致序列化失败.将属性声明为IList<T>
或IDictionary<TKey,TValue>
并使用某些具体类型实现属性是很常见的.如果通过objectsOnly = false
,则在这种情况下将抛出异常.
演示小提琴here.