DataContractJsonSerializer - 在列表与反序列化下的DateTime,对象> [英] DataContractJsonSerializer - Deserializing DateTime within List<object>

查看:173
本文介绍了DataContractJsonSerializer - 在列表与反序列化下的DateTime,对象>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用<故障href=\"http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx\"><$c$c>System.Runtime.Serialization.Json.DataContractJsonSerializer类反序列化包含在列表与LT内的DateTime实例;对象&gt; 。我似乎无法得到的DateTime反序列化回原来的类型。在 DataContractJsonSerializer 总是反序列化到一个字符串类型的格式/日期(1329159196126-0500)/。它会序列化和反序列化的罚款,如果我运行它通过使用强类型列表&LT; D​​ateTime的&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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆