SilverLight学习笔记--Silverligh之Json的通讯传递

    JSON是一种轻量级的数据传输类型,它可以通过序列化把一个简单对象转换为一个简单的字符串,在网络中进行传输,然后在客户端进行反序列化,得到原始对象.功能上和XML差不多,只是它的体积小,在客户端解析方便,所以被广泛使用.
   我们可以使用Silverlight提供的三个类来完成JSON数据的传递和接收。它们是:   

      1 、DataContractJsonSerializer (位于 System.Runtime.Serialization.Json)
      
2 、JsonObject (位于System.Json,将JSON数据流转换成为可读写的对象)
      
3 、JsonArray (位于System.Json, 对JSON数据流转换成为JsonObject数组形式,可支持LINQ查询)

     注:如果要引用System.Runtime.Serialization.Json名空间里的Json,则必须也引用System.ServiceModel,否则Json会无法使用。在本例中,我们将使用它来进行示例。
     下面我们一起来学习在Silverlight中如何从服务器端向客户端传递Json数据。  
     新建一个Silverlight应用程序。命名为:SLJson
 (一)准备工作
  在这里,我们完成三种情况的Json数据传递。

    1 、一个Person类(其属性均为简单类型:String类型)
   
2 、Customers类,它是Person类的一个List。
   
3 、一个PersonT类(它包含另一个类 Address)

  我们要传递这三种情况的类对象实例到客户端并显示出来。
  所以,在此,我们首先要在服务器端和客户端分别建立上面的三个类。
  Person类
  服务器端代码定义如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization;//要引用System.Runtime.Serialization.Dll才能使用[DataContract]与[DataMember]属性

namespace SLJson.Web
{
    [DataContract]
    
public class Person
    {
        [DataMember]
        
public string Name { getset; }
        [DataMember]
        
public int Age { getset; }
        [DataMember]
        
public string Address { getset; }
    }
}

  客户端代码定义如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SLJson
{
    
public class Person
    {
        
public string Name { getset; }
        
public int Age { getset; }
        
public string Address { getset; }
    }
}

  Customers类
  服务器端代码定义如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.Runtime.Serialization; //要引用System.Runtime.Serialization.Dll才能使用[DataContract]与[DataMember]属性

namespace SLJson.Web
{
    [DataContract]
    
public class Customers
    {
        [DataMember]
        
public List<Person> Persons { getset; }

    }
}

  客户端代码定义如下:

ContractedBlock.gifExpandedBlockStart.gifCode
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic; //要引入此空间以使用List

namespace SLJson
{
    
public class Customers
    {
        
public List<Person> Persons { getset; }
    }
}

  PersonT类


  服务器端代码定义如下:
ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization;//要引用System.Runtime.Serialization.Dll才能使用[DataContract]与[DataMember]属性

namespace SLJson.Web
{

        [DataContract]
        
public class PersonT
        {
            [DataMember]
            
public string Name { getset; }
            [DataMember]
            
public int Age { getset; }
            [DataMember]
            
public Address Address { getset; }

         }
}

  客户端代码定义如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SLJson
{
    
    
public class PersonT
    {
     
        
public string Name { getset; }
     
        
public int Age { getset; }
    
        
public Address Address { getset; }

    }
}

  PersonT类内含的Address类
  服务器端代码定义如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.Runtime.Serialization;//要引用System.Runtime.Serialization.Dll才能使用[DataContract]与[DataMember]属性

namespace SLJson.Web
{
    [DataContract]
    
public class Address
    {
        [DataMember]
        
public string country { getset; }

        [DataMember]
        
public string city { getset; }

    }
}

  客户端代码定义如下: 

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;


namespace SLJson
{
    
public class Address
    {
        
public string country { getset; }
        
public string city { getset; }

    }
}

  至此,我们的应用程序如下图:
                        
 (二) 实现Json数据的传递。

 1、建立用户界面
 Page.xaml代码如下:

 

< UserControl x:Class = " SLJson.Page "
    xmlns
= " http://schemas.microsoft.com/winfx/2006/xaml/presentation "  
    xmlns:x
= " http://schemas.microsoft.com/winfx/2006/xaml "  
    Width
= " 400 "  Height = " 400 " >
 
< StackPanel Width = " 400 "  Height = " 400 "  Background = " Wheat " >
     
< TextBlock Text = " 获取的数据如下 "  TextAlignment = " Center "  Foreground = " Red "  Margin = " 2 "  FontSize = " 16 " ></ TextBlock >
     
< ListBox x:Name = " lstReturn "  Width = " 350 "  Height = " 220 "  Margin = " 6 " ></ ListBox >
     
< Button  x:Name = " btnGetPerson "  Width  = " 200 "  Height = " 25 "  Content = " 获取Person类数据 "  Margin = " 8 "   Click = " btnGetPerson_Click "   ></ Button >
     
< Button  x:Name = " btnGetPersonT "  Width = " 200 "  Height = " 25 "  Content = " 获取PersonT类数据 "  Margin = " 8 "  Click = " btnGetPersonT_Click " ></ Button >
     
< Button  x:Name = " btnGetCustomer "  Width = " 200 "  Height = " 25 "  Content = " 获取Customer类数据 "  Margin = " 8 "  Click = " btnGetCustomer_Click " ></ Button >
     
 
</ StackPanel >
</ UserControl >

 用户界面如下图:

                         
2、服务器端:我们新建一个Handler(在本例命名为:CustomerJsonHandler.ashx)专门负责响应客户端发来的请求,在服务器端生成Json格式的结果数据并返回给客户端。

  2.1、生成将要传递的类对象实例 

ContractedBlock.gif ExpandedBlockStart.gif Code
ContractedBlock.gifExpandedBlockStart.gif        获取需要返回的数据Person#region 获取需要返回的数据Person
        
public Person GetRetDataPerson()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            Person PWang 
= new Person() { Name = "WangXiangMin", Age = 25, Address = "China" };

            
return PWang;
        }


        
#endregion


ContractedBlock.gifExpandedBlockStart.gif        
获取需要返回的数据Customers(Person类数组)#region 获取需要返回的数据Customers(Person类数组)
        
public Customers GetRetDataCustomers()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            Customers myCustomer 
= new Customers();

ExpandedSubBlockStart.gifContractedSubBlock.gif            Person PWang 
= new Person() { Name = "WangXiangMin", Age = 25, Address = "China" };
ExpandedSubBlockStart.gifContractedSubBlock.gif            Person PJack 
= new Person() { Name = "Jack", Age = 18, Address = "USA" };
ExpandedSubBlockStart.gifContractedSubBlock.gif            Person PTom 
= new Person() { Name = "Tom", Age = 32, Address = "OZ" };

            List
<Person> MyPersonList = new List<Person> 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                PWang, 
                PJack, 
                PTom
             }
;

            myCustomer.Persons 
= MyPersonList;
            
return myCustomer;
        }


        
#endregion


ContractedBlock.gifExpandedBlockStart.gif        
获取需要返回的数据PersonT(其属性Address是另一个类Address)#region 获取需要返回的数据PersonT(其属性Address是另一个类Address)
        
public PersonT GetRetDataPersonT()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            Address HongKongAddress 
= new Address() { city = "HongKong", country = "China" };
ExpandedSubBlockStart.gifContractedSubBlock.gif            PersonT PWang 
= new PersonT() { Name = "WangXiangMin", Age = 25, Address=HongKongAddress};

            
return PWang;
        }


        
#endregion

  2.2、并把它们序列化成Json格式的数据

ContractedBlock.gif ExpandedBlockStart.gif Code
            //定义一个字符串存放序列化后的结果
            string strJSON="";

            
switch (retType)
            {

                
//返回Person类
                case "Person": strJSON = SerializeToJsonString(GetRetDataPerson());  break;

                
//返回PersonT类
                case "PersonT": strJSON = SerializeToJsonString(GetRetDataPersonT());  break;

                
// 返回Person类数组Customer
                case "Customer": strJSON = ToJson<Customers>(GetRetDataCustomers()); break;
                 
            }

  2.3、向客户端传递

 

            context.Response.ContentType  =   " text/plain " ;
            context.Response.Write(strJSON);
服务器端CustomerJsonHandler.ashx全部代码如下:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;


using System.IO;
using System.Text;
using System.Runtime.Serialization.Json;//需要引用 System.ServiceModel.DLL


//需要引入System.Runtime.Serializatio.DLL

namespace SLJson.Web
ExpandedBlockStart.gifContractedBlock.gif
{
    
public class CustomerJsonHandler : IHttpHandler
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{

        
public void ProcessRequest(HttpContext context)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
//读取从客户端传来的参数
            string retType =context.Request.QueryString["retType"];

            
//定义一个字符串存放序列化后的结果
            string strJSON="";

            
switch (retType)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{

                
//返回Person类
                case "Person": strJSON = SerializeToJsonString(GetRetDataPerson());  break;

                
//返回PersonT类
                case "PersonT": strJSON = SerializeToJsonString(GetRetDataPersonT());  break;

                
// 返回Person类数组Customer
                case "Customer": strJSON = ToJson<Customers>(GetRetDataCustomers()); break;
                 
            }

 
            context.Response.ContentType 
= "text/plain";

            context.Response.Write(strJSON);
        }



ContractedSubBlock.gifExpandedSubBlockStart.gif        
获取需要返回的数据Person#region 获取需要返回的数据Person
        
public Person GetRetDataPerson()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            Person PWang 
= new Person() { Name = "WangXiangMin", Age = 25, Address = "China" };

            
return PWang;
        }


        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
获取需要返回的数据Customers(Person类数组)#region 获取需要返回的数据Customers(Person类数组)
        
public Customers GetRetDataCustomers()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            Customers myCustomer 
= new Customers();

ExpandedSubBlockStart.gifContractedSubBlock.gif            Person PWang 
= new Person() { Name = "WangXiangMin", Age = 25, Address = "China" };
ExpandedSubBlockStart.gifContractedSubBlock.gif            Person PJack 
= new Person() { Name = "Jack", Age = 18, Address = "USA" };
ExpandedSubBlockStart.gifContractedSubBlock.gif            Person PTom 
= new Person() { Name = "Tom", Age = 32, Address = "OZ" };

            List
<Person> MyPersonList = new List<Person> 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                PWang, 
                PJack, 
                PTom
             }
;

            myCustomer.Persons 
= MyPersonList;
            
return myCustomer;
        }


        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
获取需要返回的数据PersonT(其属性Address是另一个类Address)#region 获取需要返回的数据PersonT(其属性Address是另一个类Address)
        
public PersonT GetRetDataPersonT()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            Address HongKongAddress 
= new Address() { city = "HongKong", country = "China" };
ExpandedSubBlockStart.gifContractedSubBlock.gif            PersonT PWang 
= new PersonT() { Name = "WangXiangMin", Age = 25, Address=HongKongAddress};

            
return PWang;
        }


        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
序列化处理:把一个object序列化成Json字符串#region 序列化处理:把一个object序列化成Json字符串
        
public string SerializeToJsonString(object objectToSerialize)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
using (MemoryStream ms = new MemoryStream())
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                DataContractJsonSerializer serializer 
= new DataContractJsonSerializer(objectToSerialize.GetType());
                serializer.WriteObject(ms, objectToSerialize);
                ms.Position 
= 0;
                
using (StreamReader reader = new StreamReader(ms))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
return reader.ReadToEnd();
                }

            }

        }

        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
序列化处理:把一个object对象序列化成Json字符串#region  序列化处理:把一个object对象序列化成Json字符串
        
private string ToJson<T>(T obj)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            DataContractJsonSerializer ds 
= new DataContractJsonSerializer(typeof(T));
            MemoryStream ms 
= new MemoryStream();
            ds.WriteObject(ms, obj);
            
string strJSON = Encoding.UTF8.GetString(ms.ToArray());
            ms.Close();
            
return strJSON;
        }

        
#endregion




        
public bool IsReusable
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return false;
            }

        }

    }

}

3、客户端:
Page.xaml.cs中进行处理,完成的主要工作包括
 3.1、接收来自服务器端的Json格式的数据。
 3.2、反序列化这些数据,生成对应的类对象。
 3.3、解析和显示数据内容
客户端Page.xaml.cs全部代码如下:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using System.IO;
using System.Text;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.ServiceModel;

namespace SLJson
ExpandedBlockStart.gifContractedBlock.gif
{
    
public partial class Page : UserControl
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
//定义一个标志,记录当前所取的数据类型: Person,PersonT或Customer
        string flatStr = "";  

        
public Page()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            InitializeComponent();
        }

        
private void btnGetPerson_Click(object sender, RoutedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            flatStr 
= "Person";
            GetReturnJsonData(flatStr); 
        }


        
private void btnGetPersonT_Click(object sender, RoutedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            flatStr 
= "PersonT";
            GetReturnJsonData(flatStr);
        }


        
private void btnGetCustomer_Click(object sender, RoutedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            flatStr 
= "Customer";
            GetReturnJsonData(flatStr);
        }


ContractedSubBlock.gifExpandedSubBlockStart.gif        
向Handler提交读取数据请求并处理和显示返回的数据#region  向Handler提交读取数据请求并处理和显示返回的数据
        
private void GetReturnJsonData(string retType)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            Uri endpoint 
= new Uri(String.Format("http://localhost:61688/CustomerJsonHandler.ashx?retType={0}", retType), UriKind.Absolute); //指定上传地址
            WebClient client = new WebClient();
            client.DownloadStringCompleted 
+= new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);

            client.DownloadStringAsync(endpoint);
        }

        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
读取从Handler传来的数据,并进行反序列化#region 读取从Handler传来的数据,并进行反序列化
        
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
string RetStr = "";
            
if (e.Error == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{

                RetStr 
= e.Result;

                
switch(flatStr)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
case "Person": Person myPerson = Deserialize<Person>(RetStr);//获取Person类(所有属性均为简单类型)         
                                   ShowPerson(myPerson);
                                   
break;
                    
case "PersonT": PersonT myPersonT = Deserialize<PersonT>(RetStr);  //获取PersonT类(内含另一个类 Address做为它的一个属性)       
                                   ShowPerson(myPersonT);
                                   
break;
                    
case "Customer": Customers myCustomer = Deserialize<Customers>(RetStr);// 获取Customers类(它是Person类对象数组)
                                   ShowPerson(myCustomer);
                                   
break;  
                }

                RetStr 
= e.Result;
            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                RetStr 
= e.Error.Message;
            }



        }

        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
显示所取得的数据内容#region 显示所取得的数据内容
        
void ShowPerson(Person p)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
this.lstReturn.Items.Clear(); //选清空以前的显示内容
            this.lstReturn.Items.Add(p.Name);
            
this.lstReturn.Items.Add(p.Age);
            
this.lstReturn.Items.Add(p.Address);
        }


        
void ShowPerson(PersonT p)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
this.lstReturn.Items.Clear(); //选清空以前的显示内容
            this.lstReturn.Items.Add(p.Name);
            
this.lstReturn.Items.Add(p.Age);
            
this.lstReturn.Items.Add("地址Address如下");
            
this.lstReturn.Items.Add(p.Address.city);
            
this.lstReturn.Items.Add(p.Address.country);
        }


        
void ShowPerson(Customers ct)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
this.lstReturn.Items.Clear(); //选清空以前的显示内容

            
for (int i = 0; i < ct.Persons.Count;i++ )
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
this.lstReturn.Items.Add(""+i.ToString()+"个人的信息如下:");
                
this.lstReturn.Items.Add(ct.Persons[i].Name);
                
this.lstReturn.Items.Add(ct.Persons[i].Age );
                
this.lstReturn.Items.Add(ct.Persons[i].Address);
            }

        }


        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
指定类处理反序列化方法: 对传入的结果进行JSON反序列化操作并返回Person类#region 指定类处理反序列化方法: 对传入的结果进行JSON反序列化操作并返回Person类
        
public static Person DeserializeToPerson(string jsonString)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                DataContractJsonSerializer serializer 
= new DataContractJsonSerializer(typeof(Person));
                
return (Person)serializer.ReadObject(ms);
            }

        }

        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
泛型处理反序列化方法: 对传入的结果进行JSON反序列化操作并返回指定的类型#region 泛型处理反序列化方法: 对传入的结果进行JSON反序列化操作并返回指定的类型
        
public static T Deserialize<T>(string jsonString)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                DataContractJsonSerializer serializer 
= new DataContractJsonSerializer(typeof(T));
                
return (T)serializer.ReadObject(ms);
            }

        }


        
#endregion

    }

}

运行后的效果如下:
                        

前往:Silverlight学习笔记清单

本文程序在Silverlight2.0和VS2008环境中调试通过。本文参照了部分网络资料,希望能够抛砖引玉,大家共同学习。
(转载本文请注明出处)

转载于:https://www.cnblogs.com/wsdj-ITtech/archive/2009/08/27/1554787.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值