.net2.0和.net 3.5关于 json序列化的实现

关于json序列化,有3种解决方案

1:Json.NET    (第三方组件,有.net 2.0版本和.net 3.5的版本)

2 :DataContractJsonSerializer  (asp.net 3.5自带的序列化)

3:JavaScriptSerializer (asp.net 3.5自带的序列化)

先来看看.net 3.5的Json序列化

使用System.Web.Script.Serialization.JavaScriptSerializer类 (.net 3.5自带,.net 2.0无)


System.Web.Script.Serialization.JavaScriptSerializer类是.NET类库中自带的一种JSON序列化实现,在.NET Framework3.5及以后版本中可以使用这个类,这个类位于System.Web.Extensions.dll中,使用这个类是必须添加对这个dll的引用。
  下面的代码是使用JavaScriptSerializer进行序列化和反序列化的例子:

public static void JavaScriptSerializerDemo()
{
 	User user =new User { 
	UserId =1, 
	UserName ="李刚", 
	CreateDate = DateTime.Now.AddYears(-30),
	Birthday=DateTime.Now.AddYears(-50), 
	Priority = Priority.Highest, 
      Salary =500000 
};

 //JavaScriptSerializer类在System.Web.Extensions.dll中,注意添加这个引用
 JavaScriptSerializer serializer =new JavaScriptSerializer();

 //JSON序列化
string result=serializer.Serialize(user);
 Console.WriteLine("使用JavaScriptSerializer序列化后的结果:{0},长度:{1}", result, result.Length);

 //JSON反序列化
 user = serializer.Deserialize<User>(result);
 Console.WriteLine("使用JavaScriptSerializer反序列化后的结果:UserId:{0},UserName: {1},CreateDate:{2},Priority:{3}", 
user.UserId, user.UserName, user.CreateDate, user.Priority);

}
 

使用DataContractJsonSerializer类将类型实例序列化

为JSON字符串,并将JSON字符串反序列化为类型实例。 DataContractJsonSerializer在System.Runtime.Serialization.Json命名空间下

,.NET Framework 3.5包含在System.ServiceModel.Web.dll中,需要添加对其的引用;.NET Framework 4在System.Runtime.Serialization中。


 

然后在.net 2.0里面的 Json序列化


在.NET 2.0中没有内置序列化JSON的类,原因估计是当时Ajax尚未兴起。后来就有人写了一个Json.NET类库

下面Json.NET ,   DataContractJsonSerializer 以及 JavaScriptSerializer 的支持特性对比

 Json.NETDataContractJsonSerializerJavaScriptSerializer
Supports JSON   
Supports BSON   
Supports JSON Schema    
Supports .NET 2.0   
Supports .NET 3.5    
Supports .NET 4.0   
Supports Silverlight   
Supports Windows Phone   
Supports WinRT   
Open Source   
MIT License   
LINQ to JSON   (这个特性只有Json.NET才有)   
Thread Safe   
XPath-like JSON query syntax (类似xpath查询语法的JSON)   
Indented JSON support (缩进JSON支持)   
Efficient dictionary serialization (高效字典序列化)   
Nonsensical dictionary serialization   
Deserializes IList, IEnumerable, ICollection, IDictionary properties

(反序列化IList,IEnumerable,ICollection,IDictionary属性)

   
Serializes circular references   
Supports serializing objects by reference   
Deserializes polymorphic properties and collections   
Serializes and deserializes multidimensional arrays   
Supports including type names with JSON   
Globally customize serialization process   
Supports excluding null values when serializing   
Supports SerializationBinder   
Conditional property serialization   
Includes line number information in errors   
Converts XML to JSON and JSON to XML
(转换XML到JSON  ,  转换到JSON到XML)
   
JSON Schema validation  (JSON模式验证)   
JSON Schema generation from .NET types   
Camel case JSON property names (驼峰式大小写JSON属性名)   
Non-default constructors support   
Serialization error handling  (序列化错误处理)   
Supports populating an existing object   
Efficiently serializes byte arrays as base64 text   
Handles NaN, Infinity, -Infinity and undefined   
Handles JavaScript constructors   
Serializes .NET 4.0 dynamic objects   
Serializes ISerializable objects   
Supports serializing enums to their text name   
JSON recursion limit support   
Attribute property name customization   
Attribute property order customization   
Attribute property required customization   
Supports ISO8601 dates   
Supports JavaScript constructor dates   
Supports Microsoft AJAX dates   
Unquoted property names support   
Raw JSON support   
Supports reading and writing comments   
Serializes anonymous types   
Deserializes anonymous types   
Opt-in mode serialization   
Opt-out mode serialization   
Field (Serializable) mode serialization   
Efficiently stream reading and writing JSON   
Single or double quote JSON content   
Supports overriding a type's serialization   
Supports OnDeserialized, OnSerializing, OnSerialized and OnDeserializing attributes   
Supports serializing private properties   
DataMember attribute support   
MetdataType attribute support   
DefaultValue attribute support   
Serializes DataSets and DataTables   
Serailizes Entity Framework   
Serializes nHibernate   
Case-insensitive property deserialization   

 

下载 Json.NET 4.5 Release 11 (source + binary)

利用Jquery让返回的各类数据(string、集合(List<>)、类)以Json数据格式返回,为什么要用到result.d

这里我们顺带讲下Json

Json简单讲就是Javascript对象或数组.

 Json形式一: javascript对象    { "firstName": "Brett", "lastName":"McLaughlin", "email": "aaaa" }   

  Json形式二: javascript数组    [{ "firstName": "Brett", "lastName":"McLaughlin", "email": "aaaa" },{ "firstName": "Jason", "lastName":"Hunterwang", "email": "bbbb"}]

  当然javascript 数组和对象可以互相嵌套.如形式一中的"Brett"可以换成一个Js数组或Js对象.那微软的Ajax返回的是哪种形式呢.是第一种.

  微软框架默认返回一个  { "d": "后台返回的数据" } 这里我们用以上示例中的测试到得比如  

  如上例的返回的是string类型的话Firefox调试如下 

当返回的是List<>类型的话FireFox调试如下

返回的数据也是放在Js对象中的d属性里面 所以说这就是为什么我们老是用result.d来取微软的框架返回的数据.

 

在.net 3.5里面,如果是使用 linq直接把List<Product>进行返回的话,返回来的数据都是纯粹的json对象,而不是json字符串(区别就是 返回回来的数据的开头有没有 "" )

但是就算是返回的是 json的对象,也要仔细看看是返回的单个的json对象,还是json对象的数组

image

image

image

在火狐里面看是这样的

image

image

 

 

如果是在.net 3.5里面使用自带的JavaScriptSerializer 进行序列化,那么返回的数据,是 json 字符串,需要在前台用 js的 eval 或者$.parseJSON 转换成json对象

image

在火狐看是这样的

image

 

image

在火狐看是这样的

image

同样的数据,在.net 2.0里面,使用 Json.net 进行json 序列化之后,返回的也是 json字符串,并且通过 json.net序列化的时间,是有点问题的

image

在火狐里面是

image 

image

 

那么这些json字符串前台,就需要通过 jquery的  函数,转换为  json对象,才可以正常的在前台通过  对象.productname  或者 对象.productid来访问

var jqueryjson = jQuery.parseJSON(result.d);   //jQuery.parseJSON   //$.parseJSON


接受一个JSON字符串,返回解析后的对象。
传入一个畸形的JSON字符串会抛出一个异常。

比如下面的都是畸形的JSON字符串: (正确的规律是,键值对,键必须是双引号,值可以双引号,也不可以不要双引号)
{test: 1} ( test 没有包围双引号)
{'test': 1} (使用了单引号而不是双引号)

另外,如果你什么都不传入,或者一个空字符串、null或undefined,parseJSON都会返回 null 。

 

 

 

把json字符串,转换为 json对象,或者直接使用 eval ,也是可以的

var dataObj=eval("("+result.d+")");//转换为json对象

 

 

 

 

 

 

 

 

下面是部分的代码,.net 3.5下用 linq 返回后台的数据,这种情况下,默认返回的json就是json对象,所以前台不用再 eval 来转换

前台 default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="web._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(function () {

        })

        function showAll() {
            $.ajax({

                type: "GET",  //当前台ajax用get方式的时候,后台asmx页面的方法的UseHttpGet 必须为 true

                contentType: "application/json; charset=utf-8",

                url: "ProductService.asmx/GetAllProduct",

                dataType: "json",

                success: insertCallback,

                error: errorCallback

            });
        }
        function showOne() {

            var idNumber = $("#txtId").val();
            $.ajax({

                type: "POST",   //当前台ajax用post方式的时候,后台asmx页面的方法的UseHttpGet 必须为 false

                data: "{id:" + idNumber + ",tt:" + new Date().getTime() + "}",  //这里传值和后台的必须一样或者是多余后台的参数列表,例如后台是id,这里也必须是id,但是我这里还是多传了一个值,代表刷新时间,防止有缓存

                contentType: "application/json; charset=utf-8",

                url: "ProductService.asmx/GetByProductId",

                dataType: "json",

                success: insertCallback,

                error: errorCallback

            });
        }

        function insertCallback(result) {

            alert(result.d);
            alert(typeof(result.d));
            $('#productList > thead').empty();
            $('#productList > tbody').empty();

            //json返回来的数据默认就是 d 
            if (result["d"] == null) {//如果result["d"]   为 null ,则表示没有查询到想对应的值
                alert("没有数据");
                return;
            }
            //清空原来的数据

            $('#productList > thead:last').append('<tr><td>产品名称</td><td>价格</td><td>库存</td></tr>');

            if (result["d"] != null && result["d"].length == undefined) { //既不是空,但是长度又是未定义,就表示只有1个值

                $('#productList > tbody:last').append('<tr><td>' + result["d"].ProductName + '</td><td>' + result["d"].Price + '</td><td>' + result["d"].Stock + '</td></tr>');
            }
            else {
                for (var i = 0; i < result["d"].length; i++) {

                    var product = eval(result["d"][i]);

                    $('#productList > tbody:last').append('<tr><td>' +

                product.ProductName + '</td><td>' +

                product.Price + '</td><td>' +

                product.Stock + '</td></tr>');

                }
            }


        }

        function errorCallback(XMLHttpRequest, textStatus, errorThrown) {

            $('#productList > thead').empty();
            $('#productList > tbody').empty();

            alert(errorThrown + ':' + textStatus);

        } 


    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div id="listContainer" class="container">
        <div id="title">
            <br />
&nbsp;<input id="btnAll" type="button" value="通过get方式显示所有的产品" onclick="showAll()" /><br />
            <br />
            <br>
            请输入要搜索的产品ID :<input type="text" id="txtId">
            <input id="btnOne" type="button" value="通过post方式显示1个产品" onclick="showOne()" />
        </div>
        <table id="productList">
            <thead>
            </thead>
            <tbody>
            </tbody>
        </table>
    </div>
    </form>
</body>
</html>

后台 ProductService.asmx  , 没有使用序列化,而是直接返回 List<product> 类型,或者是 Product 类型,所以前台返回的是 json 对象,而不是json字符串

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Script.Services;  //如果想使用ScriptMethod,则必须引用此命名空间

namespace web
{
    /// <summary>
    /// ProductService 的摘要说明
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
     [System.Web.Script.Services.ScriptService] //这句话就是,如果你想在前台想用jquery或者是其他的ajax来调用下面的带有WebMethod的方法,那么这个注释就要去掉,问题是这个只有.net 3.5有,如果是.net 2.0呢?怎么解决?
    public class ProductService : System.Web.Services.WebService
    {
        private ProductData datasouuce  //这里是一个属性
        {
            get
            {
                return new ProductData();
            }
        }
         

        /// <summary>获取所有的产品
        /// 
        /// </summary>
        /// <returns></returns>
        [WebMethod(Description = "获取所有的产品")]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)] 
                                        //ResponseFormat:方法要返回的类型,一般为Json或者XML    
                                        //UseHttpGet:true表示前台的ajax是通过“Get”可以访问此方法,如果通过POST,报错
                                                   //false表示前台的ajax是通过"post"来访问此方法,如果通过get,报错
        public List<Product> GetAllProduct()
        {
            return datasouuce.GetAllProduct();
        }

        /// <summary>根据产品ID,返回一个产品
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [WebMethod(Description = "根据产品ID,返回一个产品")]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = false)]//这里限制前台必须是post一个id过来,而不是get方式
        public  Product GetByProductId(string id)
        {
            return datasouuce.GetByProductId(Convert.ToInt32(id));
        }

        /// <summary>根据价格,返回符合价格相同的产品列表
        /// 
        /// </summary>
        /// <param name="price"></param>
        /// <returns></returns>
        [WebMethod(Description="根据价格,返回符合价格相同的产品列表")]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)]
        public List<Product> GetByPrice(decimal price)
        {
            return datasouuce.GetByPrice(price);
        }
    }
}

后台 ProductData.cs,定义了 产品的List,并且直接返回 List<product>或者是通过 linq 直接返回一个 product

using System;
using System.Collections.Generic;
using System.Web;
using System.Linq;

namespace web
{
    public class ProductData
    {
        private List<Product> plist = new List<Product> { 
        
            new Product(){ProductId=1,ProductName="笔记本", Price=10000, Stock=10},

            new Product(){ProductId=2,ProductName="格子绒长袖衬衫", Price=90, Stock=20},

            new Product(){ProductId=3,ProductName="纯棉长袖T恤", Price=99, Stock=40},

            new Product(){ProductId=4,ProductName="炫彩T恤", Price=67, Stock=30},

            new Product(){ProductId=5,ProductName="直筒裤男牛仔裤", Price=100, Stock=20},

             new Product(){ProductId=6,ProductName="[无印严选]纯色V领长袖T恤", Price=67, Stock=50},

            new Product(){ProductId=7,ProductName="英伦学院派马夹", Price=44, Stock=40},

            new Product(){ProductId=8,ProductName="纯棉连帽宽松卫衣", Price=66, Stock=30},

            new Product(){ProductId=9,ProductName="纯棉多口袋工装裤", Price=80, Stock=990},

            new Product(){ProductId=10,ProductName="假两件长袖T恤", Price=89, Stock=30},


        };

        /// <summary>返回所有的产品
        /// 
        /// </summary>
        /// <returns></returns>
        public List<Product> GetAllProduct()
        {
            return plist;
        }

        /// <summary>根据产品ID,返回一个产品
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Product GetByProductId(int id)
        {
            return plist.FirstOrDefault(p => p.ProductId == id);
        }

        /// <summary>根据价格,返回符合价格相同的产品列表
        /// 
        /// </summary>
        /// <param name="price"></param>
        /// <returns></returns>
        public List<Product> GetByPrice(decimal price)
        {
            return plist.Where(p => p.Price == price).ToList();
        }
    }
}

 

 

如果是在 .net 3.5下,使用JavaScriptSerializer 来序列化,那么前台返回的还是 json字符串,那么前台获取值的时候,是需要 eval或者是jquery进行json转换的.

 

如果是在 .net 2.0的情况下,后台不能用 asms 来使用 webmethod给前台ajax调用,所以只能用  aspx.cs 里面写方法,并且给方法加  webmethod,并且写成静态方法给前台ajax调用,返回的json字符串

前台需要对json字符串,进行eval或者是jquery的json转换

后台 test.aspx.cs代码

using System;
using System.Collections.Generic;

using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Newtonsoft.Json;// 这个json.net在.net 2.0的情况下给本身拓展支持Linq
using System.Web.Services;

namespace FanShe.Web
{
    public partial class action : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
        public static List<Product> plist = new List<Product> { 
        
            new Product(){ProductId=1,ProductName="笔记本", Price=10000, Stock=10,AddTime=DateTime.Now},

            new Product(){ProductId=2,ProductName="格子绒长袖衬衫", Price=90, Stock=20,AddTime=DateTime.Now},

            new Product(){ProductId=3,ProductName="纯棉长袖T恤", Price=99, Stock=40},

            new Product(){ProductId=4,ProductName="炫彩T恤", Price=67, Stock=30},

            new Product(){ProductId=5,ProductName="直筒裤男牛仔裤", Price=100, Stock=20},

             new Product(){ProductId=6,ProductName="[无印严选]纯色V领长袖T恤", Price=67, Stock=50},

            new Product(){ProductId=7,ProductName="英伦学院派马夹", Price=44, Stock=40},

            new Product(){ProductId=8,ProductName="纯棉连帽宽松卫衣", Price=66, Stock=30},

            new Product(){ProductId=9,ProductName="纯棉多口袋工装裤", Price=80, Stock=990},

            new Product(){ProductId=10,ProductName="假两件长袖T恤", Price=89, Stock=30},


        };
        [WebMethod]
        public static string ListToJson()
        {
            return JsonConvert.SerializeObject(plist);
        }
        [WebMethod]
        public static string Test()
        {
            //string temp = JsonConvert.SerializeObject(temp);

            return JsonConvert.SerializeObject(plist);
        }

        [WebMethod]
        public static string ToJson1()
        {
            var user = new
            {
                name = "jey",
                age = "18",
                address = "罗湖区田蜜路",
                mobile = new
                {
                    telephone = "02784655336",
                    ydmobile = "15871152147",
                    dxmobile = "18036574142",
                    ltmobile = "12365147893"
                },
            };
            return JsonConvert.SerializeObject(user);
        }
        [WebMethod]
        public static string ToJson1Array()
        {
            var user = new[]{
            new {
                name = "joey1",
                age = "18",
                address = "罗湖区田蜜路",
                mobile = new
                {
                    telephone = "02784655336",
                    ydmobile = "15871152147",
                    dxmobile = "18036574142",
                    ltmobile = "12365147893"
                },
            },
            new {
                name = "joey2",
                age = "18",
                address = "罗湖区田蜜路",
                mobile = new
                {
                    telephone = "02784655336",
                    ydmobile = "15871152147",
                    dxmobile = "18036574142",
                    ltmobile = "12365147893"
                },
            }
            };
            return JsonConvert.SerializeObject(user);
        }
        [WebMethod]
        public static string ToJson2()
        {
            var result = new
            {
                hero = new { name = "zhouping", age = "16" },
                user = new[] { 
                    new { name = "liudehua", age = "55" }, 
                    new { name = "zhm", age = "43" } }
            };
            return JsonConvert.SerializeObject(result);
        }
    }

        [Serializable]
    public class Product
    {
        public long ProductId { get; set; }//产品ID

        public string ProductName { get; set; }

        public decimal Price { get; set; }

        public int Stock { get; set; }//产品储存量

        public DateTime AddTime { get; set; }

    }
}

转载于:https://www.cnblogs.com/joeylee/archive/2012/11/26/2789407.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值