本文是客户端访问Web Service--参数类型的序列化与反序列化(一) 这篇文章的后续部分.今天学习的主要内容是使用JavaScriptConverter,自定义JavaScriptConverter以及序列化等内容.
四、使用JavaScriptVonverter
使用JavaScriptConverter的作用就是返回一个复杂类型,但可能会出现“循环引用”的错误。那我们该怎么解决呢,一种方式是我们可以采用自定义数据类型来封装复杂类型;通过使用web.config,在web.config里定义Converter.
我们还是分析示例吧,定义一个DataTableWebService.asmx,提供一个方法返回一个DataTable对象:
[WebMethod]
public DataTable GetDataTable()
{
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("ID", typeof(int)));
dt.Columns.Add(new DataColumn("Text", typeof(string)));
Random random = new Random(DateTime.Now.Millisecond);
for (int i = 0; i < 10; i++)
{
dt.Rows.Add(i, random.Next().ToString());
}
return dt;
}
新建一个aspx页面来调用这个WebService所提供的方法:
<script type="text/javascript">
function getDataTable()
{
DataTableWebService.GetDataTable(onSucceeded,onFailed);
}
//成功时候的回调函数
function onSucceeded(result)
{
alert(result);
}
//失败时候的回调函数
function onFailed(error)
{
alert(error.get_message());
}
</script>
我们提供一个失败时候的回掉函数,当调用失败我们就把错误信息给提示出来。这样在页面调用就会发生一个错误。我们通过一个按扭来调用,当点击按扭的时候就调用getDataTable()方法,运行结果会alert出一个错误,如下图:
是什么原因造成这个错误的呢?这个错误提示信息的表示:“在序列化这个类型(DataTable)的时候发生了一个程循环的引用”。也就是说,因为有循环的引用,我们不能简单的将这个对象序列化。那么我们该怎么做呢。我们可以通过ASP.NET AJAX ctp组件提供的一个动态库("Microsoft.Web.Preview.dll”)来处理,这里我们需将其引入项目中。他指定了一些转换DataSet,DataTable,DataRow的类型。使用他我们需要在Web.config的WebService节点中添加相宜的配置。
<jsonSerialization>
<converters>
<add name="DataSetConverter" type="Microsoft.Web.Preview.Script.Serialization.Converters.DataSetConverter, Microsoft.Web.Preview" />
<add name="DataRowConverter" type="Microsoft.Web.Preview.Script.Serialization.Converters.DataRowConverter, Microsoft.Web.Preview" />
<add name="DataTableConverter" type="Microsoft.Web.Preview.Script.Serialization.Converters.DataTableConverter, Microsoft.Web.Preview" />
</converters>
</jsonSerialization>
通过这样的配置后,我们就可以正确的转换了。WebService返回了一个DataTable对象。客户端接收到result里。下面我们通过拼接字符串的形式来动态的构造一个表格在页面上呈现出来:
var sb = new Sys.StringBuilder("<table border='1'>");
sb.append("<tr><td>ID</td><td>Text</td></tr>");
for (var i = 0; i < result.rows.length; i++)
{
sb.append( String.format( "<tr><td>{0}</td><td>{1}</td></tr>", result.rows[i]["ID"],
result.rows[i].Text));
}
sb.append("</table>");
$get("result").innerHTML = sb.toString();
这就是JavaScriptConverter的用法,下面是运行结果图:
五、自定义JavaScriptConverter
往往我们在使用JavaScriptConverter的时候,我们可能会自定义一个负责的类型,那么在序列化的时候也可能会出现循环引用的情况,处于这种情况我们就可以自己定义一个JavaScriptConverter。那么我们该如何定义这个JavaScriptConverter呢?JavaScriptConverter的作用就是处理循环引用,简化默认的复杂序列化和反序列化的行为。我们首先先定义两个负责的类型:
public class Boy
{
public string Name;
public Girl GirlFriend;
}
public class Girl
{
public string Name;
public Boy BoyFriend;
}
定义JavaScriptConverter我们需定义一个类继承JavaScriptConverter类,并实现SupportedTypes及Serialize方法用于序列化复杂数据;实现SupportenTypes:
public override IEnumerable<Type> SupportedTypes
{
get { yield return typeof(Boy); }
}
实现Serialize用户序列化复杂数据:
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
Boy boy = (Boy)obj;
IDictionary<string, object> result = new Dictionary<string, object>();
result["Name"] = boy.Name;
boy.GirlFriend.BoyFriend = null;
result["GirlFriend"] = boy.GirlFriend;
return result;
}
实现Deserialize方法用于反序列化复杂数据:
public override object Deserialize(IDictionary<string, object> dictionary,
Type type, JavaScriptSerializer serializer)
{
Boy boy = new Boy();
boy.Name = (string)dictionary["Name"];
boy.GirlFriend = serializer.ConvertToType<Girl>(dictionary["GirlFriend"]);
boy.GirlFriend.BoyFriend = boy;
return boy;
}
到这里我们自定义的JavaScriptConverter就算是万事具备,只欠东风了。这东风从何起呢?我们已经定义好了JavaScriptConverter,最后一步就是需要在web.config里注册该JavaScriptConverter。
<add name="BoyConverter" type="BoyConverter, App_Code" />
接下来我们来看看我们怎么来使用自定义的这个JavaScriptConverter,客户端代码:
<script language="javascript" type="text/javascript">
function getBoy()
{
BoyGirlService.GetBoyWithGirlFriend(onGetBoySucceeded, onFailed);
}
function onGetBoySucceeded(result)
{
// result.GirlFriend.BoyFriend = result;
alert(String.format(
"他是 {0}, 他的女朋友是 {1}",
result.Name,
result.GirlFriend.Name));
}
function onFailed(error)
{
alert(error.get_message());
}
function setBoy()
{
var boy = new Object();
boy.Name = "李四";
var girl = new Object();
girl.Name = "王玫";
boy.GirlFriend = girl;
BoyGirlService.SetBoyWithGirlFriend(boy, onSetBoySucceeded, onFailed);
}
function onSetBoySucceeded(result)
{
alert(result);
}
</script>
同样我们还是通过按扭来实现调用,当点击按纽的时候就得到复杂数据或是设置数据。
1<input type="button" value="Get Boy" onclick="getBoy()" />
2<input type="button" value="Set Boy" onclick="setBoy()" />
下面是运行后的效果:
实例源码见附件!!
分享到:
相关推荐
- 创建一个SoapSerializationEnvelope实例,将SoapObject放入其中,以确保SOAP消息的序列化和反序列化。 - 创建一个HttpTransportSE实例,通过它将SOAP请求消息发送到服务器,并接收响应。 - 使用上述实例调用Web ...
在这个"Web service 序列化实验教程"中,我们将专注于如何使用XML进行序列化,这是Web服务中一个至关重要的环节。XML(eXtensible Markup Language)是一种标记语言,常用于数据交换,因为它具有良好的可读性和平台...
3. **数据序列化与反序列化**:客户端可能需要将数据转换为JSON或XML格式,以便于在网络间传输。C#提供了`JsonSerializer`(System.Text.Json)或`DataContractSerializer`(用于.NET Framework的WCF服务)等工具...
- **序列化和反序列化**:`System.Text.Json`或第三方库如Newtonsoft.Json用于JSON数据的序列化和反序列化,便于在客户端和服务端之间传递对象。 5. **项目结构**: - `Restful-Service-And-Restful-Client-...
在WCF服务中,当服务方法需要返回一个对象或者接受一个对象作为参数时,就需要进行序列化。序列化是将对象转换为字节流的过程,以便可以通过网络进行传输。反序列化则是相反的过程,将接收到的字节流恢复为原来的...
2. **实现自定义序列化**: 定义自定义类型`CustomSerializedObject`,并使用`IXmlSerializable`接口来实现自定义序列化和反序列化。这个接口有两个方法需要实现:`ReadXml` 和 `WriteXml`。 ```csharp public class...
- **数据类型转换**:确保数组元素的数据类型与Web Service期望的数据类型相匹配。 - **序列化**:数组需要按照SOAP规范进行序列化。 - **解析响应**:处理返回的SOAP响应时,注意正确地反序列化数组数据。 #### 七...
2. **SOAP消息处理**:gSOAP提供了处理SOAP消息的接口,包括序列化和反序列化对象、发送和接收SOAP消息等。 3. **跨语言互操作性**:虽然gSOAP主要针对C和C++,但生成的Web Service可以被其他语言的客户端访问,如...
描述中提到的“支持类的传输”意味着在Java调用.NET Web Service时,不仅传递基本类型的数据,还能传递复杂的对象,这通常需要序列化和反序列化的支持。在.NET中,我们可以使用DataContract和DataMember特性标记类...
- **XML 数据类型到 Java 类型的映射**:实现数据序列化。 - **可扩展类型映射**:支持自定义数据类型的映射。 - **SOAP Message Handler 框架**:处理 SOAP 消息的框架。 - **打包**:将 Web Service 打包成...
总的来说,C#调用Java WebService的过程涉及到多个技术层面,包括XML序列化、网络通信、数据类型转换以及错误处理。理解这些细节对于实现跨平台的应用集成至关重要。在实际开发中,还需要根据具体项目需求进行适当的...
在Web Service的上下文中,Compact DataSet可以作为在服务器和客户端之间传递数据的有效方式,因为它占用的内存更少,而且在序列化和反序列化过程中效率较高。 Web Service通常用于跨平台、跨系统的数据交换,但...
在这个"WebService Axis1.4接口服务序列/反序列复杂项目实例"中,我们将深入探讨如何在 Axis1.4 中处理复杂的参数、自定义实体对象的序列化与反序列化,以及客户端的复杂调用。 首先,让我们理解序列化和反序列化的...
这在JSON Web Service中至关重要,因为服务需要接收和发送JSON格式的数据,以实现与客户端的有效通信。 在使用这些库构建JSON Web Service时,开发人员首先需要导入这些jar文件到他们的项目中。然后,他们可以利用...
3. **数据类型映射**:gSOAP支持多种数据类型的自动转换,包括基本数据类型、结构体、枚举等,使得C/C++代码可以直接操作这些类型,而无需关心底层的XML序列化和反序列化过程。 4. **HTTP和HTTPS支持**:gSOAP不仅...
5. **客户端消费服务**:创建一个WCF客户端,调用服务的方法,此时就会涉及数据的序列化和反序列化。 ```csharp var client = new MyServiceClient(); Person person = new Person() { Name = "John", Age = 30 }; ...
### Web Coverage Processing Service (WCPS) — OGC标准解析 #### 概述 《Web Coverage Processing Service (WCPS) Language Interface Standard》(OGC 08-068r2)是Open Geospatial Consortium(开放地理空间...
1. **检查XML序列化与反序列化**:确保客户端和服务器使用的数据类型匹配,并且XML序列化正确。可以使用XML查看器工具检查发送的SOAP消息是否符合预期。 2. **校验命名空间**:确保客户端和服务器使用的命名空间...