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分

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM