JSON是一种轻量级的数据传输类型,它可以通过序列化把一个简单对象转换为一个简单的字符串,在网络中进行传输,然后在客户端进行反序列化,得到原始对象.功能上和XML差不多,只是它的体积小,在客户端解析方便,所以被广泛使用.
我们可以使用Silverlight提供的三个类来完成JSON数据的传递和接收。它们是: DataContractJsonSerializer 、JsonObject 、JsonArray 。 如果要引用DataContractJsonSerializer ,则必须也引用System.ServiceModel,否则Json会无法使用。在本例中,我们将使用DataContractJsonSerializer 来进行示例。
下面我们一起来学习在Silverlight中如何从服务器端向客户端传递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类
服务器端代码定义如下:
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 { get; set; }
[DataMember]
public int Age { get; set; }
[DataMember]
public string Address { get; set; }
}
}
客户端代码定义如下:
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 { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}
}
Customers类
服务器端代码定义如下:
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 { get; set; }
}
}
客户端代码定义如下:
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;
using System.Collections.Generic; //要引入此空间以使用List
namespace SLJson
{
public class Customers
{
public List<Person> Persons { get; set; }
}
}
PersonT类
服务器端代码定义如下:
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 { get; set; }
[DataMember]
public int Age { get; set; }
[DataMember]
public Address Address { get; set; }
}
}
客户端代码定义如下:
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 { get; set; }
public int Age { get; set; }
public Address Address { get; set; }
}
}
PersonT类内含的Address类
服务器端代码定义如下:
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 { get; set; }
[DataMember]
public string city { get; set; }
}
}
客户端代码定义如下:
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 { get; set; }
public string city { get; set; }
}
}
至此,我们的应用程序如下图:
(二) 实现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、生成将要传递的类对象实例
Code
获取需要返回的数据Person#region 获取需要返回的数据Person
public Person GetRetDataPerson()
{
Person PWang = new Person() { Name = "WangXiangMin", Age = 25, Address = "China" };
return PWang;
}
#endregion
获取需要返回的数据Customers(Person类数组)#region 获取需要返回的数据Customers(Person类数组)
public Customers GetRetDataCustomers()
{
Customers myCustomer = new Customers();
Person PWang = new Person() { Name = "WangXiangMin", Age = 25, Address = "China" };
Person PJack = new Person() { Name = "Jack", Age = 18, Address = "USA" };
Person PTom = new Person() { Name = "Tom", Age = 32, Address = "OZ" };
List<Person> MyPersonList = new List<Person>
{
PWang,
PJack,
PTom
};
myCustomer.Persons = MyPersonList;
return myCustomer;
}
#endregion
获取需要返回的数据PersonT(其属性Address是另一个类Address)#region 获取需要返回的数据PersonT(其属性Address是另一个类Address)
public PersonT GetRetDataPersonT()
{
Address HongKongAddress = new Address() { city = "HongKong", country = "China" };
PersonT PWang = new PersonT() { Name = "WangXiangMin", Age = 25, Address=HongKongAddress};
return PWang;
}
#endregion
2.2、并把它们序列化成Json格式的数据
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全部代码如下:
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
{
public class CustomerJsonHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
//读取从客户端传来的参数
string retType =context.Request.QueryString["retType"];
//定义一个字符串存放序列化后的结果
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;
}
context.Response.ContentType = "text/plain";
context.Response.Write(strJSON);
}
获取需要返回的数据Person#region 获取需要返回的数据Person
public Person GetRetDataPerson()
{
Person PWang = new Person() { Name = "WangXiangMin", Age = 25, Address = "China" };
return PWang;
}
#endregion
获取需要返回的数据Customers(Person类数组)#region 获取需要返回的数据Customers(Person类数组)
public Customers GetRetDataCustomers()
{
Customers myCustomer = new Customers();
Person PWang = new Person() { Name = "WangXiangMin", Age = 25, Address = "China" };
Person PJack = new Person() { Name = "Jack", Age = 18, Address = "USA" };
Person PTom = new Person() { Name = "Tom", Age = 32, Address = "OZ" };
List<Person> MyPersonList = new List<Person>
{
PWang,
PJack,
PTom
};
myCustomer.Persons = MyPersonList;
return myCustomer;
}
#endregion
获取需要返回的数据PersonT(其属性Address是另一个类Address)#region 获取需要返回的数据PersonT(其属性Address是另一个类Address)
public PersonT GetRetDataPersonT()
{
Address HongKongAddress = new Address() { city = "HongKong", country = "China" };
PersonT PWang = new PersonT() { Name = "WangXiangMin", Age = 25, Address=HongKongAddress};
return PWang;
}
#endregion
序列化处理:把一个object序列化成Json字符串#region 序列化处理:把一个object序列化成Json字符串
public string SerializeToJsonString(object objectToSerialize)
{
using (MemoryStream ms = new MemoryStream())
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(objectToSerialize.GetType());
serializer.WriteObject(ms, objectToSerialize);
ms.Position = 0;
using (StreamReader reader = new StreamReader(ms))
{
return reader.ReadToEnd();
}
}
}
#endregion
序列化处理:把一个object对象序列化成Json字符串#region 序列化处理:把一个object对象序列化成Json字符串
private string ToJson<T>(T obj)
{
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
{
get
{
return false;
}
}
}
}
3、客户端:
在Page.xaml.cs中进行处理,完成的主要工作包括
3.1、接收来自服务器端的Json格式的数据。
3.2、反序列化这些数据,生成对应的类对象。
3.3、解析和显示数据内容
客户端Page.xaml.cs全部代码如下:
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
{
public partial class Page : UserControl
{
//定义一个标志,记录当前所取的数据类型: Person,PersonT或Customer
string flatStr = "";
public Page()
{
InitializeComponent();
}
private void btnGetPerson_Click(object sender, RoutedEventArgs e)
{
flatStr = "Person";
GetReturnJsonData(flatStr);
}
private void btnGetPersonT_Click(object sender, RoutedEventArgs e)
{
flatStr = "PersonT";
GetReturnJsonData(flatStr);
}
private void btnGetCustomer_Click(object sender, RoutedEventArgs e)
{
flatStr = "Customer";
GetReturnJsonData(flatStr);
}
向Handler提交读取数据请求并处理和显示返回的数据#region 向Handler提交读取数据请求并处理和显示返回的数据
private void GetReturnJsonData(string retType)
{
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
读取从Handler传来的数据,并进行反序列化#region 读取从Handler传来的数据,并进行反序列化
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
string RetStr = "";
if (e.Error == null)
{
RetStr = e.Result;
switch(flatStr)
{
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
{
RetStr = e.Error.Message;
}
}
#endregion
显示所取得的数据内容#region 显示所取得的数据内容
void ShowPerson(Person p)
{
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)
{
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)
{
this.lstReturn.Items.Clear(); //选清空以前的显示内容
for (int i = 0; i < ct.Persons.Count;i++ )
{
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
指定类处理反序列化方法: 对传入的结果进行JSON反序列化操作并返回Person类#region 指定类处理反序列化方法: 对传入的结果进行JSON反序列化操作并返回Person类
public static Person DeserializeToPerson(string jsonString)
{
using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Person));
return (Person)serializer.ReadObject(ms);
}
}
#endregion
泛型处理反序列化方法: 对传入的结果进行JSON反序列化操作并返回指定的类型#region 泛型处理反序列化方法: 对传入的结果进行JSON反序列化操作并返回指定的类型
public static T Deserialize<T>(string jsonString)
{
using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
return (T)serializer.ReadObject(ms);
}
}
#endregion
}
}
运行后的效果如下:
前往:Silverlight学习笔记清单
本文程序在Silverlight2.0和VS2008环境中调试通过。本文参照了部分网络资料,希望能够抛砖引玉,大家共同学习。
(转载本文请注明出处)