如何使用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看起来像:

 { "TypedValue": { "__type": "TypedSurrogateOfdateTime:#Question39973917", "Value": "/Date(1476244800000)/" } }