DataContractJsonSerializer - 在列表与反序列化下的DateTime,对象&gt; [英] DataContractJsonSerializer - Deserializing DateTime within List<object>
问题描述
我在使用<故障href=\"http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx\"><$c$c>System.Runtime.Serialization.Json.DataContractJsonSerializer$c$c>类反序列化包含在列表与LT内的DateTime实例;对象&gt;
。我似乎无法得到的DateTime反序列化回原来的类型。在 DataContractJsonSerializer
总是反序列化到一个字符串类型的格式/日期(1329159196126-0500)/
。它会序列化和反序列化的罚款,如果我运行它通过使用强类型列表&LT; DateTime的&GT;
,但是我正在寻找方式来获得串行识别并正确地反序列化DateTime是否当对象的简单列表或数组中遇到
。
注意,DateTime是否是除了原语,而且这个名单将永远包含字符串的唯一类型。
这里是code片断我用来测试。
VAR名单=新名单,LT;对象&gt; {27,富巴,12.34米,真实,DateTime.Now};
VAR串行=新DataContractJsonSerializer(typeof运算(列表&LT;对象&gt;));
使用(MemoryStream的毫秒=新的MemoryStream())
{
serializer.WriteObject(MS,清单);
ms.Position = 0;
VAR deserializedList = serializer.ReadObject(MS)的名单,LT;对象&gt ;;
}
这似乎是很奇怪的现象,我的猜测是,它从日期时间不是就是在JSON株型识别一个类型的茎。但是,您可以推出自己IDataContractSurrogate修改序列化/反序列化过程。
要在创建序列化到这个使用这个修改您的样本code:
VAR串=新DataContractJsonSerializer(typeof运算(列表&LT;对象&gt;),空,int.MaxValue,假的,新DateTimeDataContractSurrogate(),TRUE);
然后加入这个类:
公共类DateTimeDataContractSurrogate:IDataContractSurrogate
{
私人静态只读正则表达式dateRegex =新的正则表达式(@/日期\\((\\ D +)([ - +])(\\ d +)\\)/);
私人静态只读的DateTime划时代=新日期时间(1970年,1,1,0,0,0,DateTimeKind.Utc); 公共对象GetCustomDataToExport(类型clrType,类型dataContractType)
{
// 不曾用过
返回null;
} 公共对象GetCustomDataToExport(System.Reflection.MemberInfo的MemberInfo,类型dataContractType)
{
// 不曾用过
返回null;
} 公共类型GetDataContractType(类型类型)
{
// 不曾用过
返回类型;
} 公共对象GetDeserializedObject(obj对象,类型TARGETTYPE)
{
//调试
//Console.WriteLine(\"GetDeserializedObject:OBJ = {0}({1}),TARGETTYPE = {2},OBJ,obj.GetType(),TARGETTYPE); //只作用于表&LT;对象&gt;类型
如果(obj.GetType()== typeof运算(列表&LT;对象&gt;))
{
VAR objList =(列表&LT;对象&gt;)目标文件; 清单&LT;对象&gt; copyList =新的List&LT;对象&gt;(); //一个列表值复制到。这将是返回的列表。
的foreach(在objList VAR项)
{
字符串s =项目作为字符串;
如果(S!= NULL)
{
//检查是否符合DateTime格式
匹配匹配= dateRegex.Match(S);
如果(match.Success)
{
//试图解析字符串转换为长。然后创建一个datetime和转换为本地时间。
长msFromEpoch;
如果(long.TryParse(match.Groups [1] .value的,出msFromEpoch))
{
时间跨度fromEpoch = TimeSpan.FromMilliseconds(msFromEpoch);
copyList.Add(TimeZoneInfo.ConvertTimeFromUtc(epoch.Add(fromEpoch),TimeZoneInfo.Local));
继续;
}
}
} copyList.Add(项目); //添加未修改
} 返回copyList;
} 返回OBJ;
} 公共无效GetKnownCustomDataTypes(System.Collections.ObjectModel.Collection&LT;类型&GT; customDataTypes)
{
// 不曾用过
} 公共对象GetObjectToSerialize(obj对象,类型TARGETTYPE)
{
//调试
//Console.WriteLine(\"GetObjectToSerialize:OBJ = {0}({1}),TARGETTYPE = {2},OBJ,obj.GetType(),TARGETTYPE);
返回OBJ;
} 公共类型GetReferencedTypeOnImport(字符串的typeName,串typeNamespace,的CustomData对象)
{
// 不曾用过
返回null;
} 公共系统。codeDOM。codeTypeDeclaration ProcessImportedType(系统。codeDOM。codeTypeDeclaration typeDeclaration,系统。codeDOM。codeCompileUnit compileUnit)
{
// 不曾用过
返回typeDeclaration;
}
}
I'm having trouble using the System.Runtime.Serialization.Json.DataContractJsonSerializer
class to deserialize DateTime instances contained within a List<object>
. I cannot seem to get DateTime to deserialize back into the original type. The DataContractJsonSerializer
always deserializes it into a string type with the format "/Date(1329159196126-0500)/"
. It'll serialize and deserialize fine if I run it through using a strongly typed List<DateTime>
, however I am looking for way to get the serializer to identify and properly deserialize DateTimes when encountered within a simple list or array of object
.
Note that DateTimes are the only type besides primitives and strings that this list will ever contain. Here is the code snippet I'm using to test this.
var list = new List<object> { 27, "foo bar", 12.34m, true, DateTime.Now };
var serializer = new DataContractJsonSerializer(typeof (List<object>));
using (MemoryStream ms = new MemoryStream())
{
serializer.WriteObject(ms, list);
ms.Position = 0;
var deserializedList = serializer.ReadObject(ms) as List<object>;
}
This seems like very strange behavior, my guess is that it stems from DateTime not being a type that is recongnized in JSON. However, you can roll your own IDataContractSurrogate to modify the serialization/deserialization process.
To use this modify your sample code when you create the the serializer to this:
var serializer = new DataContractJsonSerializer(typeof(List<object>), null, int.MaxValue, false, new DateTimeDataContractSurrogate(), true);
Then add this class:
public class DateTimeDataContractSurrogate : IDataContractSurrogate
{
private static readonly Regex dateRegex = new Regex(@"/Date\((\d+)([-+])(\d+)\)/");
private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public object GetCustomDataToExport(Type clrType, Type dataContractType)
{
// not used
return null;
}
public object GetCustomDataToExport(System.Reflection.MemberInfo memberInfo, Type dataContractType)
{
// not used
return null;
}
public Type GetDataContractType(Type type)
{
// not used
return type;
}
public object GetDeserializedObject(object obj, Type targetType)
{
// for debugging
//Console.WriteLine("GetDeserializedObject: obj = {0} ({1}), targetType = {2}", obj, obj.GetType(), targetType);
// only act on List<object> types
if (obj.GetType() == typeof(List<object>))
{
var objList = (List<object>)obj;
List<object> copyList = new List<object>(); // a list to copy values into. this will be the list returned.
foreach (var item in objList)
{
string s = item as string;
if (s != null)
{
// check if we match the DateTime format
Match match = dateRegex.Match(s);
if (match.Success)
{
// try to parse the string into a long. then create a datetime and convert to local time.
long msFromEpoch;
if (long.TryParse(match.Groups[1].Value, out msFromEpoch))
{
TimeSpan fromEpoch = TimeSpan.FromMilliseconds(msFromEpoch);
copyList.Add(TimeZoneInfo.ConvertTimeFromUtc(epoch.Add(fromEpoch), TimeZoneInfo.Local));
continue;
}
}
}
copyList.Add(item); // add unmodified
}
return copyList;
}
return obj;
}
public void GetKnownCustomDataTypes(System.Collections.ObjectModel.Collection<Type> customDataTypes)
{
// not used
}
public object GetObjectToSerialize(object obj, Type targetType)
{
// for debugging
//Console.WriteLine("GetObjectToSerialize: obj = {0} ({1}), targetType = {2}", obj, obj.GetType(), targetType);
return obj;
}
public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
{
// not used
return null;
}
public System.CodeDom.CodeTypeDeclaration ProcessImportedType(System.CodeDom.CodeTypeDeclaration typeDeclaration, System.CodeDom.CodeCompileUnit compileUnit)
{
// not used
return typeDeclaration;
}
}
这篇关于DataContractJsonSerializer - 在列表与反序列化下的DateTime,对象&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!