.NET Framework 3.5中序列化成JSON数据及JSON数据的反序列化,以及jQuery的调用JSON

53 篇文章 0 订阅
原贴地址:http://bbs.zkinfo.com/thread-80510-1-1.html

最近要用到jQuery调用JSON,但遇到几个问题,正面将记录下遇到的问题及解决方法。
在将Object序列化成JSON时普遍是使用以下几种方式:
1. 第三方组件Newtonsoft.Json.dll来序列化。
2. 直接用StringBuilder拼接字符串。
3. .NET3.5中的DataContractJsonSerializer
很多人使用的是第三方组件来序列化,但.NET3.5中已经提供了对序列化及反序列化很好的支持,直接使用就行了,而拼接字符串的方式就更原始了,要对一 些字符串进行处理也容易出错。所以还是选择了DataContractJsonSerializer,感觉非常方便。下面就看怎么来实了:
首先创建项目,添加必要的程序集引用:System.ServiceModel.Web及System.Runtime.Serialization
创建ashx文件以便jQuery调用,当然也可以根据自己的需要创建WebServices或其它文件,代码如下
Demo.ashx
Demo.ashx
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Web;
using System.Web.Services;

namespace JSONDemo
{
   
///
<summary>
/// $codebehindclassname$ 的摘要说明
   
///
</summary>
    [WebService(Namespace =
" http://tempuri.org/ " )]
    [WebServiceBinding(ConformsTo
= WsiProfiles.BasicProfile1_1)]
   
public
class Demo : IHttpHandler
    {
        
public
void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType
=
" text/plain " ;
            List
< User > users =
new List < User > ();
            
#region AddUser
            users.Add(
new User
            {
                UserId
=
1 ,
                UserName
=
" 张三 " ,
                Birthday
= DateTime.Parse( " 1982/1/1 " )
            });
            users.Add(
new User
            {
                UserId
=
2 ,
                UserName
=
" 李四 " ,
                Birthday
= DateTime.Parse( " 1983/2/1 " )
            });
            users.Add(
new User
            {
                UserId
=
3 ,
                UserName
=
" 王五 " ,
                Birthday
= DateTime.Parse( " 1984/3/1 " )
            });
            
#endregion
string json = JsonHelper.Serialize(users);
            
// context.Response.Write("序列化:/r/n");
            context.Response.Write(json);
            
// User u = JsonHelper.Deserialize<User>("");
            List < User > users2 = JsonHelper.Deserialize < List < User >> (json);
            
// context.Response.Write("/r/n反序列化:/r/n");

foreach (User item in users2)
            {
               
// context.Response.Write(string.Format("UserId:{0},UserName:{1},Birthday:{2}/r/n", item.UserId, item.UserName, item.Birthday));
            }
        }

        
public
bool IsReusable
        {
            
get
            {
               
return
false ;
            }
        }
    }

   
///
<summary>
/// 数据实体
   
///
</summary>

// [Serializable]这里是需要注意的地方

public
class User
    {
        
public
int UserId { get ; set ; }
        
public
string UserName { get ; set ; }
        
public DateTime Birthday { get ; set ; }
    }

   
///
<summary>
/// JSON序列化与反序列化辅助类
   
///
</summary>

public
class JsonHelper
    {
        
public
static
string Serialize < T > (T data)
        {
            System.Runtime.Serialization.Json.DataContractJsonSerializer serializer
=
new System.Runtime.Serialization.Json.DataContractJsonSerializer(data.GetType());
            
using (MemoryStream ms =
new MemoryStream())
            {
                serializer.WriteObject(ms, data);
               
return Encoding.UTF8.GetString(ms.ToArray());
               
// ms.Position = 0;
               
// using (StreamReader sr = new StreamReader(ms))
               
// {
               
//     return sr.ReadToEnd();
               
// }
            }
        }

        
public
static T Deserialize < T > ( string json)
        {
            T obj
= Activator.CreateInstance < T > ();
            
using (MemoryStream ms =
new MemoryStream(Encoding.UTF8.GetBytes(json)))
            {
                System.Runtime.Serialization.Json.DataContractJsonSerializer serializer
=
new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType());
               
return (T)serializer.ReadObject(ms);
            }
        }
    }
}


访问Demo.ashx显示结果如下,对了这就是我们想要的数据:
[{ " Birthday " : " //Date(378662400000+0800)// " , " UserId " : 1 , " UserName " : " 张三 " },{ " Birthday " : " //Date(412876800000+0800)// " , " UserId " : 2 , " UserName " : " 李四 " },{ " Birthday " : " //Date(446918400000+0800)// " , " UserId " : 3 , " UserName " : " 王五 " }]

jQuery调用JSON代码:

jQuery调用
< script type = " text/javascript " >
    $().ready(
function () {
        $.getJSON(
" Demo.ashx " , function (data) {
            
var msg = [data.length];
            
for ( var i in data) {
                msg
=
"UserId:"
+ data.UserId +
",UserName:"
+ data.UserName +
",Birthday:"
+ data.Birthday;
            }
            alert(msg.join(
'/n'));
        });
    });
</script>


但在实现时遇到几个问题:
1. DateTime类型在实例化时如果未对DateTime属性赋值序列化时(即:DateTime.MinValue)将会报错:指定的参数已超出有效值的范围。参数名: value
在转换为 UTC 时大于 DateTime.MaxValue 或小于 DateTime.MinValue 的 DateTime 值无法系列化为 JSON。]

根据提示是DateTime值小于DateTime.MinValue时造成的,但实际上未赋值时DateTime默认就是MinValue了,不存在小 于MinValue。莫然其妙的一个问题,但如果DateTime值为DateTime.MinValue.AddDays(1),就没问题了。所以提示 应该改成必须大于MinValue,不知道这算不算一个小BUG?
2. 当最开始序列化时发现虽然序列化的结果却是下面这样一堆字符:

[{"<Birthday>k__BackingField":"//Date(378662400000+0800)//","<UserId>k__BackingField":1,"<UserName>k__BackingField":"张三"},{"<Birthday>k__BackingField":"//Date(412876800000+0800)//","<UserId>k__BackingField":2,"<UserName>k__BackingField":"李四"},{"<Birthday>k__BackingField":"//Date(446918400000+0800)//","<UserId>k__BackingField":3,"<UserName>k__BackingField":"王五"}]

经查询是因为实体类声明了可序列化造成的:
[Serializable]
public class User
当然把[Serializable]去掉,结果就正常了,可这样实体类就不能实例化了?当然我们可以用其它方法来解决这一问题,用WCF中的数据契约声明实体就行(别忘了在所有属性上加上[DataMember]不然这些属性都不可访问哦。)[DataContract]
public class User
{
     [DataMember]
     public int UserId{get;set;}
}


完整DEMO下载:JSONDemo.rar
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Json.NET 描述: json。 网络是一个流行的高性能JSON为。NET框架 灵活的JSON序列化器对之间的转换。净对象和JSON linq到JSON用于手动阅读和写作JSON 高性能,速度比。净的内置JSON序列化器 写缩进,容易阅读JSON JSON和XML之间进行转换 支持: .NET 2, .NET 3.5, .NET 4, .NET 4.5, Silverlight, Windows Phone and Windows 8 Store 版本: Json.NET has different libaries for the various .NET Framework versions. -Net45: .NET latest (4.5) -Net40: .NET 4.0 -Net35: .NET 3.5 -Net20: .NET 2.0 -WinRT: Windows 8 Store -Portable45: .NET 4.5, Windows Phone 8, Windows 8 Store -Portable40: .NET 4.0, Windows Phone 7, Windows 8 Store, Silverlight 4 Notes: Microsoft stopped support for the Compact Framework in Visual Studio 2010. For a Compact Framework 3.5 build download Json.NET 3.5. For a Silverlight 3.0 build download Json.NET 3.5. Microsoft Visual Studio 2010 重新生解决方案的一些警告处理 警告 2 预定义类型“System.Action”是在全局别名的多个程序集定义的;将使用“c:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework \v4.0\mscorlib.dll”的定义 ClassLibrary1 警告 3 预定义类型“System.Action”是在全局别名的多个程序集定义的;将使用“c:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework \v4.0\mscorlib.dll”的定义 ClassLibrary1 警告 4 预定义类型“System.Action”是在全局别名的多个程序集定义的;将使用“c:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework \v4.0\mscorlib.dll”的定义 ClassLibrary1 警告 5 预定义类型“System.Action”是在全局别名的多个程序集定义的;将使用“c:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework \v4.0\mscorlib.dll”的定义 ClassLibrary1 警告 6 预定义类型“System.Func”是在全局别名的多个程序集定义的;将使用“c:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework \v4.0\mscorlib.dll”的定义 ClassLibrary1 警告 7 预定义类型“System.Func”是在全局别名的多个程序集定义的;将使用“c:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework \v4.0\mscorlib.dll”的定义 ClassLibrary1 警告 8 预定义类型“System.Func”是在全局别名的多个程序集定义的;将使用“c:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework \v4.0\mscorlib.dll”的定义 ClassLibrary1 警告 9 预定义类型“System.Func”是在全局别名的多个程序集定义的;将使用“c:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework \v4.0\mscorlib.dll”的定义 ClassLibrary1 警告 10 预定义类型“System.Func”是在全局别名的多个程序集定义的;将使用“c:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework \v4.0\mscorlib.dll”的定义 ClassLibrary1 问题原因:检查程序发现,由于项目引用了Newtonsoft.Json.Net20,从而造系统的类重名(项目FRAMEWORK的版本4.0)。 Newtonsoft.Json.Net 包括: .NET 2, .NET 3.5, .NET 4, .NET 4.5, Silverlight, Windows Phone and Windows 8 Store,所有dll文件和源码,有需要的同学可以直接下载。 个人网站多多支持:www.mlyuansu.com
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值