首页 > 代码库 > JavaScriptSerializer中日期序列化问题解决方案

JavaScriptSerializer中日期序列化问题解决方案

JavaScriptSerializer中日期序列化问题解决方案

直接进入主题:

 

class Student    {        public int age { get; set; }        public DateTime? date { get; set; }        public string name { get; set; }    }

 

 当点击的时候:

   private void button1_Click(object sender, EventArgs e)        {            System.Web.Script.Serialization.JavaScriptSerializer js = new System.Web.Script.Serialization.JavaScriptSerializer();            List<Student> list = new List<Student>();            list.Add(new Student()            {                age = 10,                date = DateTime.Now,                name = "宋兴柱  是个好孩\"子,这里\"有英文逗号"            });            //js.RegisterConverters(new JavaScriptConverter[] { new DateTimeConverter() });            var str = js.Serialize(list);            //str = Regex.Replace(str, @"\\/Date\((\d+)\)\\/", match =>            //{            //    DateTime dt = new DateTime(1970, 1, 1);            //    dt = dt.AddMilliseconds(long.Parse(match.Groups[1].Value));            //    dt = dt.ToLocalTime();            //    return dt.ToString("yyyy-MM-dd HH:mm:ss");            //});            //var obj = js.Deserialize<List<Student>>(str);            textBox1.Text = str;        }


这个时候,显示如下内容:[{"age":10,"date":"\/Date(1404098342309)\/","name":"宋兴柱  是个好孩\"子,这里\"有英文逗号"}]

显然,这里的DateTime 类型被替换成了:\/Date(1404098342309)\/,经过分析,其实这个1404098342309数值,是1970年1月1日(DateTime的最小值)到date实际表示的日期之差的总毫秒数。

因此,这里提供2种解决方案。

方案1 :

  private void button1_Click(object sender, EventArgs e)        {            System.Web.Script.Serialization.JavaScriptSerializer js = new System.Web.Script.Serialization.JavaScriptSerializer();            List<Student> list = new List<Student>();            list.Add(new Student()            {                age = 10,                date = DateTime.Now,                name = "宋兴柱  是个好孩\"子,这里\"有英文逗号"            });            //js.RegisterConverters(new JavaScriptConverter[] { new DateTimeConverter() });            var str = js.Serialize(list);            str = Regex.Replace(str, @"\\/Date\((\d+)\)\\/", match =>            {                DateTime dt = new DateTime(1970, 1, 1);                dt = dt.AddMilliseconds(long.Parse(match.Groups[1].Value));                dt = dt.ToLocalTime();                return dt.ToString("yyyy-MM-dd HH:mm:ss");            });            //var obj = js.Deserialize<List<Student>>(str);            textBox1.Text = str;        }

显示结果:[{"age":10,"date":"2014-06-30 11:22:15","name":"宋兴柱  是个好孩\"子,这里\"有英文逗号"}]
当取消var obj = js.Deserialize<List<Student>>(str);的注释之后,会发现反序列化也完全正常。因此,这算是当前的最佳方案。

方案2 :

如果用户的日期需求中,只用到年月日,无需时分秒的情况下:如,2014-06-30 时,可以使用如下方案:

 public class DateTimeConverter : JavaScriptConverter    {               public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)        {            return new JavaScriptSerializer().ConvertToType(dictionary, type);        }        public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)        {            if (!(obj is DateTime)) return null;            return new CustomString(((DateTime)obj).ToString("yyyy-MM-dd"));        }        public override IEnumerable<Type> SupportedTypes        {            get            {                return new[] { typeof(DateTime) };            }        }        private class CustomString : Uri, IDictionary<string, object>        {            public CustomString(string str)                : base(str, UriKind.Relative)            {            }            void IDictionary<string, object>.Add(string key, object value)            {                throw new NotImplementedException();            }            bool IDictionary<string, object>.ContainsKey(string key)            {                throw new NotImplementedException();            }            ICollection<string> IDictionary<string, object>.Keys            {                get                {                    throw new NotImplementedException();                }            }            bool IDictionary<string, object>.Remove(string key)            {                throw new NotImplementedException();            }            bool IDictionary<string, object>.TryGetValue(string key, out object value)            {                throw new NotImplementedException();            }            ICollection<object> IDictionary<string, object>.Values            {                get                {                    throw new NotImplementedException();                }            }            object IDictionary<string, object>.this[string key]            {                get                {                    throw new NotImplementedException();                }                set                {                    throw new NotImplementedException();                }            }            void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> item)            {                throw new NotImplementedException();            }            void ICollection<KeyValuePair<string, object>>.Clear()            {                throw new NotImplementedException();            }            bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> item)            {                throw new NotImplementedException();            }            void ICollection<KeyValuePair<string, object>>.CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)            {                throw new NotImplementedException();            }            int ICollection<KeyValuePair<string, object>>.Count            {                get                {                    throw new NotImplementedException();                }            }            bool ICollection<KeyValuePair<string, object>>.IsReadOnly            {                get                {                    throw new NotImplementedException();                }            }            bool ICollection<KeyValuePair<string, object>>.Remove(KeyValuePair<string, object> item)            {                throw new NotImplementedException();            }            IEnumerator<KeyValuePair<string, object>> IEnumerable<KeyValuePair<string, object>>.GetEnumerator()            {                throw new NotImplementedException();            }            IEnumerator IEnumerable.GetEnumerator()            {                throw new NotImplementedException();            }                   }

点击按钮时,注册即可:

    

 private void button1_Click(object sender, EventArgs e)        {            System.Web.Script.Serialization.JavaScriptSerializer js = new System.Web.Script.Serialization.JavaScriptSerializer();            List<Student> list = new List<Student>();            list.Add(new Student()            {                age = 10,                date = DateTime.Now,                name = "宋兴柱  是个好孩\"子,这里\"有英文逗号"            });            js.RegisterConverters(new JavaScriptConverter[] { new DateTimeConverter() });            var str = js.Serialize(list);            //str = Regex.Replace(str, @"\\/Date\((\d+)\)\\/", match =>            //{            //    DateTime dt = new DateTime(1970, 1, 1);            //    dt = dt.AddMilliseconds(long.Parse(match.Groups[1].Value));            //    dt = dt.ToLocalTime();            //    return dt.ToString("yyyy-MM-dd HH:mm:ss");            //});            //var obj = js.Deserialize<List<Student>>(str);            textBox1.Text = str;        }

执行效果如下:[{"age":10,"date":"2014-06-30","name":"宋兴柱  是个好孩\"子,这里\"有英文逗号"}]

对于方案二来说,由于内部使用的是Uri类,因此,将日期转为字符串如:2014-06-30 11:30:00这 种样式的时候,中间的空格,会被进行Url编码:空格会被编码成:%20。因此会损坏原有的日期格式。不过方案二对于其它类型的使用,依然有借鉴之处。还忘不断探索。

 

 

------------------- 繁星小宋:宋兴柱(Sindrol)于2014-06-30:11:31分