基于WCF的客户端和服务端参数传递的过程:
主要步骤:客户端序列化参数为XML信息集--传递->服务端反序列化为本地类型--执行结果->序列化结果为XML信息集--传递->客户端序反序列化返回信息为本地类型。
什么是序列化:
序列化是指将对象实例的状态存储到存储媒体的过程。在此过程中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,然后再把字节流写入数据流。在随后对对象进行反序列化时,将创建出与原对象完全相同的副本。序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。
序列化的目的:
1、以某种存储形式使自定义对象持久化;
2、将对象从一个地方传递到另一个地方。 序列化就是把本地消息或者数据的类型进行封送,转换为标准的可以跨平台、语言的信息集,为别的系统或者服务所用。
.net的序列化:
一、BinaryFormatter二进制序列化的优点:
1. 所有的类成员(包括只读的)都可以被序列化;
2. 性能高。
二、SoapFormatter、XmlSerialize的优点:
1. 跨平台,互操作性好;
2. 不依赖二进制;
3. 可读性强。
三、总述:当然.NET原有的序列化器也有自己的局限性,因为他们除了要序列化对象的状态信息外,还要将程序集的信息和版本信息持久化到流中,这样才能保证对象被反序列化为正确的对象类型副本。这要求客户端必须拥有使用.NET程序集。不能满足跨平台的WCF数据交互的需求。
WCF未捕捉的异常
特点:
1. 在缺省状态下,异常的细节不会与客户端应用程序共享,能够选择添加细节信息
2. 返回一个通用的SOAP Fault,SOAP 格式依赖于绑定(binding)
IncludeExceptionDetailsInFaults:
1. 是否打开异常细节部分将包括栈跟踪的信息
2. 为了安全起见,仅限于在开发调试时使用。
3. 其中打开和关闭有两种方式,第一种是通过配置文件的方法:
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior" >
<serviceDebug includeExceptionDetailInFaults ="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
第二种是使用ServiceBehaviorAttribute来初始化行为:
[ServiceBehaviorAttribute(IncludeExceptionDetailsInFaults=true)]
public class Service : IService
FaultException:
1. 用于抛出简单的错误
2. 可以提供错误原因与代码
3. 能够提供额外的SOAP错误元素
例如:
throw new FaultException("An invalid operation has occurred.");
throw new FaultException(new FaultReason("An invalid operation
has occurred."));
throw new FaultException(new FaultReason("An invalid operation
has occurred."), FaultCode.CreateSenderFaultCode(null));
4. 它还提供了一个泛型的支持FaultException<T>,T必须是数据契约或者可序列化类型,当然也可以是CLR异常,但是运用了CLR异常的话不利于跨平台操作,比如服务端是.net开发的,而客户端在使用的时候使用了java开发,那么这个CLR异常会难以识别。
例如:
throw new FaultException<InvalidOperationException>(new
InvalidOperationException("An invalid operation has
occured."), "Invalid operation.",
FaultCode.CreateSenderFaultCode(null));
5. 为了更好的实现跨平台,我们需要为服务错误创建数据契约
例如:
[ServiceContract(Name="PhotoUploadContract", Namespace =
"http://www.thatindigogirl.com/samples/2006/06")]
public interface IPhotoUpload
{
[OperationContract]
[FaultContract(typeof(ReceiverFault))]
[FaultContract(typeof(SenderFault))]
void UploadPhoto(PhotoLink fileInfo, byte[] fileData);
}
这里的ReceiverFault, SenderFault就是数据契约类。
MessageFault:
1. 在服务执行过程中,我们手工抛出FaultException异常,WCF服务端框架会对该异常对象进行序列化病最终生成Fault消息。当WCF客户端框架介绍到该Fault消息之后,会做一项相反的操作:对Fault消息中进行解析和反序列化,重新生成并抛出FaultException异常。WCF框架自动为我们作了这么多“幕后”工作,使得开发人员可以完全采用编写一般的.NET应用程序的模式进行异常的处理:在错误的地方抛出相应异常,对于潜在出错的方法调用进行相应的异常捕获和处理。所以,WCF的异常处理框架的核心功能就是实现FaultException异常和Fault消息之间的转换
2. 对于WCF的异常处理框架,其本身并不直接进行FaultException异常和Fault消息之间的转换,而是通过另外一个作为中介的对象来完成的,这个对象就是这一小节我们讲述的重点:MessageFault。Message(Fault)、MessageFault和FaultException。
MessageFault mfault = MessageFault.CreateFault(
FaultCode.CreateSenderFaultCode(null),
new FaultReason("Invalid operation"),
new InvalidOperationException("An invalid operation has
occurred."), null, "", "");
FaultException fe = FaultException.CreateFault(mfault,
typeof(InvalidOperationException));
throw fe;
IErrorHandler接口:
1. 定义
public interface IErrorHandler
{
void ProvideFault(Exception error, MessageVersion version, ref Message fault);
bool HandleError(Exception error);
}
2. ProvideFault 方法在服务方法发生异常,WCF 返回异常消息,终止会话之前被调用。该方法通常被用来修改返回的异常消息,诸如进行重新包装等等。由于调用 ProvideFault 时,客户端处于阻塞状态,因此不要在其内部做长时间的处理,以免客户端超时。而 HandleError 在异常返回给客户端之后被触发,因此它不会阻塞通讯。多数时候只是用来完成异常记录,进行错误提示等操作。
3. 要使用 IErrorHandler, 除了创建一个具体类型外,还要使用另外一个接口 —— IServiceBehavior。通过 IServiceBehavior 我们可以将自己的 ErrorHandler 安装到 Channel Dispatcher 异常处理集合当中。
WCF绑定:
1. 绑定表示通讯信道(communication channel)的配置
2. 绑定定义了客户端与服务端之间通讯的协议(传输协议、消息编码和安全性,可靠性消息与事务)
3. 每个绑定元素对于信道(channel)栈的某些部分进行配置
WCF绑定方式介绍:http://blog.csdn.net/shellwin/archive/2010/06/19/5680152.aspx