如何使用DataContractJsonSerializer序列化/反序列化存储在对象字段中的DateTime?
我使用以下类通过两个ASP.NET服务交换JSON数据:
[DataContract] public class Filter { [DataMember] public string Name {get; set;} [DataMember] public FilterOperator Operator {get; set;} [DataMember] public object Value {get; set;} }
这是问题:如果我在Value
设置DateTime
,它将被反序列化为字符串:
Value = "/Date(1476174483233+0200)/"
这可能是因为反序列化器无法知道最初序列化时值的类型:
JSON = {"Value":"/Date(1476174483233+0200)/"}
__type
解释的, DataContractJsonSerializer
在__type
属性的帮助下支持多态性。
我试图在类的顶部添加[KnownType(typeof(DateTime))]
属性,但它没有帮助。
但是,如果我在Value
属性(以及类中相应的KnownType
属性)中设置了一个Tuple
,它就可以工作(正确反序列化的值):
Value = {(10/11/2016 10:49:30 AM)}
在JSON内部, __type
被__type
JSON = { "Value": { "__type" : "TupleOfdateTime:#System", "m_Item1" : "/Date(1476175770028+0200)/" } }
有没有办法强制DataContractJsonSerializer
发出正确的信息来正确序列化/反序列化DateTime
(这意味着我在序列化后得到一个DateTime
而不是字符串)?
我试着在DataContractJsonSerializerSettings
设置EmitTypeInformation = EmitTypeInformation.Always
,但它没有帮助。
问题是DataContractJsonSerializer
只为与JSON对象对应的类型插入多态类型提示属性"__type"
– 一组由{
和}
包围的无序名称/值对。 如果类型映射到其他任何东西(即JSON数组或基元),则无法插入类型提示。 Stand-Alone JSON序列化中记录了此限制:
类型提示仅应用于复杂类型
无法为非复杂类型发出类型提示。 例如,如果操作具有Object返回类型但返回Circle,则JSON表示可以如前所示,并保留类型信息。 但是,如果返回Uri,则JSON表示是一个字符串,并且用于表示Uri的字符串将丢失。 这不仅适用于原始类型,也适用于集合和数组。
因此,您需要做的是修改您的Filter
类以序列化和反序列化一个通用代理对象的值,该值封装了值的类型信息,沿着Json.Net的问题中的那一行 :
[DataContract] public class Filter { [DataMember] public string Name { get; set; } [DataMember] public FilterOperator Operator { get; set; } [IgnoreDataMember] public object Value { get; set; } [DataMember] TypedSurrogate TypedValue { get { return TypedSurrogate.CreateSurrogate(Value); } set { if (value is TypedSurrogate) Value = ((TypedSurrogate)value).ObjectValue; else Value = value; } } } [DataContract] // Include some well-known primitive types. Other types can be included at higher levels [KnownType(typeof(TypedSurrogate))] [KnownType(typeof(TypedSurrogate))] [KnownType(typeof(TypedSurrogate))] [KnownType(typeof(TypedSurrogate))] [KnownType(typeof(TypedSurrogate))] [KnownType(typeof(TypedSurrogate))] [KnownType(typeof(TypedSurrogate))] [KnownType(typeof(TypedSurrogate))] [KnownType(typeof(TypedSurrogate))] [KnownType(typeof(TypedSurrogate))] [KnownType(typeof(TypedSurrogate))] [KnownType(typeof(TypedSurrogate))] [KnownType(typeof(TypedSurrogate))] [KnownType(typeof(TypedSurrogate))] [KnownType(typeof(TypedSurrogate))] [KnownType(typeof(TypedSurrogate))] [KnownType(typeof(TypedSurrogate))] [KnownType(typeof(TypedSurrogate))] public abstract class TypedSurrogate { protected TypedSurrogate() { } [IgnoreDataMember] public abstract object ObjectValue { get; } public static TypedSurrogate CreateSurrogate(T value) { if (value == null) return null; var type = value.GetType(); if (type == typeof(T)) return new TypedSurrogate (value); // Return actual type of subclass return (TypedSurrogate)Activator.CreateInstance(typeof(TypedSurrogate<>).MakeGenericType(type), value); } } [DataContract] public class TypedSurrogate : TypedSurrogate { public TypedSurrogate() : base() { } public TypedSurrogate(T value) : base() { this.Value = value; } public override object ObjectValue { get { return Value; } } [DataMember] public T Value { get; set; } }
现在你的JSON看起来像:
上述就是C#学习教程:如何使用DataContractJsonSerializer序列化/反序列化存储在对象字段中的DateTime?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
{ "TypedValue": { "__type": "TypedSurrogateOfdateTime:#Question39973917", "Value": "/Date(1476244800000)/" } }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1024915.html