我正在努力处理 .Net core 中的自定义 json 序列化,我试图默认设置所需的所有属性,除非属性具有特定类型。这是我想要实现的目标的示例:
假设我有以下类型:
F#:
type FooType = {
id: int
name: string
optional: int option
}
您可以将以下代码视为类似于 C# 中的以下代码:
class FooType =
{
int Id {get;set;};
string Name {get;set;};
Nullable<int> Optional {get;set;};
}
我想做的是,如果 json 对象中缺少 Id 或 Name 属性,则返回错误,但如果缺少Optional,则反序列化不会出现错误(因此基本上是根据需要或不根据其类型设置属性)。我可以使用以下方法根据需要标记所有属性RequireObjectPropertiesContractResolver
从这个样本:https://stackoverflow.com/a/29660550但不幸的是我无法构建更有活力的东西。
我还有可选类型的默认转换器,我想添加到序列化中。这不是这个特定问题的一部分,但如果您知道如何将属性标记为必需或不需要,并在一个地方使用自定义转换器,那么它会更好。
您可以组合合同解析器Json.NET 需要反序列化的所有属性答案的逻辑反思以确定财产是否属于期权类型 by p.s.w.g根据需要标记除可选成员之外的所有成员:
type RequireObjectPropertiesContractResolver() =
inherit DefaultContractResolver()
override __.CreateObjectContract(objectType: Type) =
let contract = base.CreateObjectContract objectType
contract.ItemRequired <- System.Nullable<Required>(Required.Always)
contract
override __.CreateProperty(memberInfo: MemberInfo, memberSerialization: MemberSerialization) =
let property = base.CreateProperty(memberInfo, memberSerialization)
// https://stackoverflow.com/questions/20696262/reflection-to-find-out-if-property-is-of-option-type
let isOption = property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() = typedefof<Option<_>>
if isOption then (
property.Required <- Required.Default
property.NullValueHandling <- new System.Nullable<NullValueHandling>(NullValueHandling.Ignore)
)
property
然后,反序列化如下:
let settings = new JsonSerializerSettings(ContractResolver = RequireObjectPropertiesContractResolver())
let obj = JsonConvert.DeserializeObject<FooType>(inputJson, settings)
Notes:
我还添加了NullValueHandling.Ignore
这样没有值的可选成员就不会被序列化。
你可能想要缓存合约解析器以获得最佳性能.
-
Option<'T>
不等于Nullable<'T>
。我检查了typedefof<Option<_>>
但你可以添加一个检查typedefof<System.Nullable<_>>
如果你想要的话:
let isOption = property.PropertyType.IsGenericType && (property.PropertyType.GetGenericTypeDefinition() = typedefof<Option<_>> || property.PropertyType.GetGenericTypeDefinition() = typedefof<System.Nullable<_>>)
Sample fiddle,这表明字符串{"id":101,"name":"John"}
可以反序列化,但是字符串{"id":101}
cannot.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)