使用DataContractSerializer

  终结点(包括地址、绑定、契约)可通过代码以编程方式添加到服务中。如:


using(ServiceHost host =new ServiceHost(typeof(DerivativesCalculator),
new Uri[] { new Uri("http://localhost:8000/Derivatives") }))
{
host.AddServiceEndpoint(typeof(IServiceViewOfService), new BasicHttpBinding(), "Calculator");
host.Open(); Console.WriteLine("The service is available."); [......]
}

  类似地,客户端亦可直接通过编程方式包含服务终结点信息,而无需引用应用程序配置的终结点信息:

string address ="http://localhost:8000/Derivatives/Calculator";
ChannelFactory<IClientViewOfService> factory =new ChannelFactory(IClientViewOfService>(
new BasicHttpBinding(),
new EndpointAddress(new Uri(address)));
IClientViewOfService proxy = factory.CreateChannel();

  DataContractSerializer能自动序列化任何实现了System.Runtime.Serialization.ISerializable接口的.NET类型。

  通过实现System.Runtime.Serialization.IExtensibleDataObject接口,类会另外分配一些空 间,这样System.Runtime.Serialization.DataContractSerializer可以用来存储、访问数据契约其他版本 可能包含的其他成员的值。这样,当同一个数据契约的更高级版本包含服务版本所没有的成员 时,System.Runtime.Serialization.DataContract-Serializer就能将这些成员的值传给服务。

  当需要使用参数类型的子类型的实例作为输入来访问服务时,就必须添加 System.ServiceModel.ServiceKnownType特性,这意味着我们应该避免使用继承关系作为数据契约升级版本的方法。如果定 义的是父类型参数,但接收到的却是子类型,除非修改代码为预测到的子类型添加System.ServiceModel.ServiceKnownType 特性,否则子类型的序列化将会失败。

  通过使用System.Runtime.Serialization.DataContract和 System.Runtime.Serialization.DataMember特性,可以非常简单地让WCF的 System.Runtime.Serializa-tion.DataContractSerializer将开发者定制的数据类型序列化。

  实现System.Runtime.Serialization.IExtensibleDataObject接口通常是一个很好的做法,因为这样同一数据契约的不同版本可以相互独立地改进,而它们又能一起使用。

  WCF对System.Runtime.Serialization.DataContractSerializer的调用被隐藏起来了,以下代码显示调用了DataContractSerializer将数据序列化成XML:

MemoryStream stream =new MemoryStream();
DataContractSerializer serializer =new DataContractSerializer(typeof(ClientViewOfData));
serializer.WriteObject(stream, calculation);
Console.WriteLine(UnicodeEncoding.UTF8.GetChars(stream.GetBuffer());

异常处理

  当服务发生异常时,数据契约也能帮助通知客户端。如下所示:


//服务器端代码
//数据契约
[DataContract]
publicclass SomeError
{
[DataMember]
publicstring Content;
} //服务接口
//利用System.ServiceModel.FaultContract特性为操作添加一个出错契约
//这将告诉客户端,服务有可能返回一个由SomeError数据契约定义的格式的错误消息,而不是返回预期的结果
[OperationContract(Name="Faulty")]
[FaultContract(typeof(SomeError))]
decimal DivideByZero(decimal input); //服务类
publicclass DerivativesCalculator : IServiceViewOfService
{
[...]
publicdecimal DivideByZero(decimal input)
{
try
{
decimal denominator =;
return input / denominator;
}
catch(Exception exception)
{
SomeError error =new SomeError();
error.Content = exception.Message;
//SomeError的实例通过FaultException<T>泛型传递给调用者
thrownew FaultException<SomeError>(error);
}
}
} //客户端代码
//手动添加接口方法和出错契约
[ServiceContract(Name="DerivativesCalculator")]
[KnownType(typeof(DerivedData))]
publicinterface IClientViewOfService
{
[...]
[OperationContract(Name="Faulty")]
[FaultContract(typeof(SomeError))]
decimal DivideByZero(decimal input);
} publicclass Program
{
publicstaticvoid Main(string[] args)
{
using(ServiceHost host =new ServiceHost(typeof(DerivativesCalculator),
new Uri[]{ new Uri("http://localhost:8000/Derivatives") }))
{
host.AddServiceEndpoint(typeof(IServiceViewOfService),
new BasicHttpBinding(), "Calculator");
host.Open(); Console.WriteLine("The service is available.");
string address ="http://localhost:8000/Derivatives/Calculator"; ChannelFactory<IClientViewOfService> factory =new ChannelFactory<IClientViewOfService>(
new BasicHttpBinding(), new EndpointAddress(new Uri(address)));
IClientViewOfService proxy = factory.CreateChannel(); [...] try
{
Decimal quotient = proxy.DivideByZero();
}
catch(FaultException<SomeError> error)
{
Console.WriteLine("Error: {0}", error.Detail.Content);
} [...]
}
}
}

  WCF也提供了给客户端返回任何在服务中发生的未预测到的异常的完整信息的功能,这通常在调度一个服务的过程中很有用。这个功能可以通过使用 System.ServiceModel-.DescriptionServiceDebugBehavior行为的 IncludeExceptionDetailInFaults属性来打开。该属性可在配置文件中设置,这将导致任何未被处理的异常都传输给客户端。但在 最后的产中版本里打开此属性将会是不安全的,因为将异常的所有信息都传递给客户端可能会暴露一些对服务会造成危害的信息。

WCF揭秘学习笔记(3):使用DataContractSerializer的更多相关文章

  1. WCF揭秘学习笔记(1):基础知识

    最近找工作,面试时经常被问懂不懂WCF.不少招聘高级.NET工程师的要求上都 写着有WCF开发经验的优先考虑.我对于WCF仅仅是通过看一些教学视频这种山寨学习法了解一些.现在要下决心好好学习一下WCF ...

  2. WCF揭秘学习笔记(2):数据表示

    背景知识 WCF提供了一种语言为软件通信建模,称作服务模型.使用更底层的编程架构提供的类可以从这种语言建立的模型中生成可用的通信软件. 在服务模型使用的语言中,负责通信的软件部分称为服务(servic ...

  3. WCF揭秘学习笔记(5):WF定制活动

    WF(Windows Workflow Foundation,Windows工作流基础)为.NET提供了一种基于模型的.声明方式的过程执行引擎,它改变了传统的通过一行行编写代码来开发服务功能的方式. ...

  4. WCF揭秘学习笔记(4):可信赖会话、会话管理、队列、事务

    可信赖会话 WCF的可信赖会话在绑定层保证消息只会被传输一次,并且保证消息间的顺序.当使用TCP通信时,协议本身保证了可靠性,但它只在两点间的网络 包这个层面提供了这样的保证.WCF的可信赖会话特性保 ...

  5. WCF双工学习笔记

    WCF双工的作用在于服务端执行某个方法的时候调用客户端的方法,有点类似委托的感觉,实际项目中在什么情况下使用还没想到. WCF双工支持两种bind,一是nettcp.另一个是wsDualHttp,这里 ...

  6. ASP.NET MVC5框架揭秘 学习笔记01

    1.自治视图 在早期(作者也没说明是多早,自己猜吧),我们倾向于将所有与UI相关的操作糅合在一起(现在我身边还有很多人这样做),这些操作包括UI界面的呈现. 用户交互操作的捕捉与响应(UI处理逻辑). ...

  7. WCF 学习笔记之异常处理

    WCF 学习笔记之异常处理 1:WCF异常在配置文件 <configuration> <system.serviceModel> <behaviors> <s ...

  8. Dynamic CRM 2013学习笔记(二十二)插件里调用WCF服务

      1. 添加service:     2.调用WCF BasicHttpBinding myBinding = new BasicHttpBinding(); myBinding.Name = &q ...

  9. WCF学习笔记之事务编程

    WCF学习笔记之事务编程 一:WCF事务设置 事务提供一种机制将一个活动涉及的所有操作纳入到一个不可分割的执行单元: WCF通过System.ServiceModel.TransactionFlowA ...

随机推荐

  1. ThinkPHP开发博客系统笔记之一

    1.前后台搭建 开发的第一步是搭建前后台系统.搭建前台系统的时候新建了LoginController控制器和登录界面View/Login/index.tpl.模板文件中需要引入js和css文件,这里想 ...

  2. shell 变量赋值运算

    .变量赋值: name=lbg 等号前后不能有空格 name="Lebron James" 变量值中有空格要用双引号 echo ${name} 用${}更保险 shopt -s - ...

  3. [原][osgearth]osgearthviewer读取earth文件,代码解析(earth文件读取的一帧)

    跑osgearthviewer程序 使用一个earth文件做参数传入 跟进代码. 首先osgearthviewer程序加载earth的方式分为两种: 1.根据earth文件(load方式) 2.使用S ...

  4. Javascript设计模式笔记

    Javascript是越来越厉害了,一统前后端开发.于是最近把设计模式又看了一遍,顺便做了个笔记,以方便自己和他人共同学习. 笔记连载详见:http://www.meteorcn.net/wordpr ...

  5. 第13课:HTML基础之DOM操作2

    1. 1)d.innerHTML:标签中的所有内容 删除某个标签 a)可以直接修改innerHTML的值: b) 2)d.innerText:标签中的文本内容 3)input.value='aaa'  ...

  6. protel 99se 全部焊盘和过孔补泪滴,很多都是失败的,对板子有影响吗?补泪滴的作用?

    泪滴     是焊盘与导线或者是导线与导孔之间的滴装连接过度,设置泪滴的目的是在电路板受到巨大外力的冲撞时,避免导线与焊盘或者导线与导孔的接触点断开,另外,设置泪滴也可使PCB电路板显得更加美观.te ...

  7. maven项目目录结构 学习笔记

    maven的约定 1.src/main/java--------------------------------存放项目的.java文件 2.src/main/resources----------- ...

  8. Windows下MySQL多实例运行

    1.正常安装Windows版的MySQL,例如安装在C:\Program Files\MySQL文件夹里: 2.按照常规配置好MySQL: (注:5.6版本的 data文件夹与 my.ini文件在C: ...

  9. python中的运算符优先级(其它语言也试用)

  10. BZOJ5091: [Lydsy1711月赛]摘苹果(简单概率)

    5091: [Lydsy1711月赛]摘苹果 Time Limit: 1 Sec  Memory Limit: 256 MBSubmit: 214  Solved: 163[Submit][Statu ...