使用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. 20145335郝昊《网络攻防》Bof逆向基础——ShellCode注入与执行

    20145335郝昊<网络攻防>Bof逆向基础--ShellCode注入与执行 实验原理 关于ShellCode:ShellCode是一段代码,作为数据发送给受攻击服务器,是溢出程序和蠕虫 ...

  2. log4j2配置按照日志级别将日志输出到不同的文件

    背景 在项目中,可能会产生非常多的日志记录,为了方便日志分析,可以将日志按级别输出到指定文件. log4j2.xml配置文件 <!--将info级别的日志单独输出到info.log中--> ...

  3. 【yum】yum的使用

    Yum官网 Yum的缓存 Yum仓库 Yum命令 Yum插件 yum的缓存 通过缓存可以提升我们环境的搭建效率,直接把原来缓存好的安装包数据放到新环境,省去了几个G的下载,甚至,有些时候客户现场不能联 ...

  4. Codeforces Round #256 (Div. 2) D. Multiplication Table 很有想法的一个二分

    D. Multiplication Table time limit per test 1 second memory limit per test 256 megabytes input stand ...

  5. python stat获取文件信息

    import os statinfo = os.stat('qqq.txt') print(statinfo,"\n") print(statinfo.st_mode) 输出 os ...

  6. python 字典添加元素

    d = {:, :} print(d) d.update({:}) print(d)

  7. bzoj1044: [HAOI2008]木棍分割 二分+dp

    有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长度最小, 并且输出有多少 ...

  8. R语言rJava包安装载入及JAVA环境配置

    rJava 包的安装与载入 一般文本分词的教程都会贴出: install.packages("rJava") library(rJava) 来引导我们装载rJava包,运行inst ...

  9. 在centos7下安装java8和mysql

    一般学习java和部署项目都是在本地部署,但是生产环境一般都是在linux环境下,部署和安装环境都是在控制台下进行操作的,没有windows的可视化的操作界面,对与linux的命令掌握和操作对小白来说 ...

  10. 分析公司shareaholic报告:Chrome浏览器使用量居首

    社交分析公司Shareaholic周四发布研究报告称,今年9月份,Chrome浏览器的使用量已经跃居行业榜首. 根据Shareaholic的数据,Chrome今年9月的使用量超过了火狐.IE和Oper ...