由于wince中对wcf的支持不是很好,所有还有需要用到传统的webservice,wince6.0和webservice通信的过程中,有时候在信号不是很稳定的情况下,容易出现“无法从传输连接中获取数据”的异常信息,因为在调试的过程中一直信号都很稳定,这就给发现原因提供了一定的困难,通过异常日志的记录,居然发现HTTP返回的状态是204(返回成功但内容为空),觉得很奇怪,明知我返回的内容不为空,但确返回此异常,并且这种提示信息让客户特别反感,带着这种疑问,于是想记录下客户端和服务器端webservice序列化成xml后在通信的过程中到底是发送了什么和接收了什么。
记录webservice序列化成xml的数据并不难,只要在webservice中添加soap扩展soapextension类的实现就行了,主要用到的方法是ChainSream和ProcessMessage
其中ProcessMessage(SoapMessage message)有四个阶段:
SoapMessageStage.BeforeDeserialize(反序列化前)、SoapMessageStage.BeforeSerialize(序列化前)、SoapMessageStage.AfterSerialize(序列化后)和SoapMessageStage.AfterDeserialize(反序列化后)
在使用过程中,需要注意以下几点:
1.不同优先级的Soap扩展在Soap消息传输的不同阶段其调用顺序是不一样的,具体可以分为两个阶段:即Serialize阶段,其调用是按照Soap扩展的优先级从低到高执行的,
在Deserialize阶段,其调用是按照Soap扩展优先级从高到低执行的。
2.ChainStream的调用是按照Soap扩展的高优先级到低优先级的调用顺序依次调用的,被执行四次.
3.离从网络传输层近的是高优先级的。并且在整个序列化和反序列化的过程中经测试为先执行chainstream然后才会执行processmessage()
4.soapextension类可能通过SoapExtensionAttribute属性类调用(针对每一个方法)也可以通过全局配置web.config,app.config配置整个使用,但由于wince不支持全局配置,故只能单个方法属性定义
5.在反序列化过程中由于会从网络传输层中首先获取数据,因此其soapmessage.stream是不为空的,而序列化则为空,需要通过在chainstream设置一缓冲区让其填充数据
别外soapextension还有三个方法:
//设置初始化属性(全局配置时使用)
public override object GetInitializer(Type serviceType)
{
return System.Web.HttpContext.Current.Request.MapPath(".")+"\\log.txt";
}
//获取SoapExtensionAttribute 调用时的属性(属性调用时使用)
public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
{
return ((ExtensionAttribute)attribute).Filename;
}
//得到GetInitializer()设置的属性
public override void Initialize(object initializer)
{
filename = (string)initializer;
}
全局config的配置代码为:
<webServices>
<soapExtensionTypes>
<add type="LYErp.MyExtension,LYErp" priority="1" group="High"/>
</soapExtensionTypes>
此例子只是记录了webservice序列化成xml的相关数据,可以用来进行测试和对xml进行加密,压缩等操作。
例子程序:
http://download.csdn.net/detail/jj516585042/4941845