如何使用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)/" } }
- 在每个非查询或整个连接之前打开连接?
- 设置ViewStateUserKey会给我一个“viewstate MAC failed的validation”错误
- HttpRequest索引器的搜索顺序
- 谁点击了从网站A到网站B的链接?
- 为什么Parallel.ForEach改变了它的线程文化?
- 每24小时后执行一次ac#function
- 如何使用c#应用程序上传和下载文件到onedrive for business?
- ASP.NET + C#HttpContext.Current.Session为null(Inside WebService)
- SignalR跨域和IIS 7.5到集线器的路径只能在服务器上本地工作,如何从外部访问它?