起名WCF技术分析之二十一:WCF基本好处理情势[中篇]

摘要

数据库性能对软件全体性有紧要的影响,对于Mongodb数据库常用之习性优化措施要有:

  1. 范式化与反范式化;
  2. 填充因子的使;
  3. 目标动;

照理说,大家早就不易定义了错明细类型CalculationError,在Calculator瑟维斯(Service)的Divide操作中便足以一向抛来一个Fault<CalculationError>,并以一个创设一个CalculationError对象作为该老对象的细(通过Detail属性表示),具体的代码如下所示:

1.2. 相反范式化

1.2.1 反范式化的助益:

  1. 足避关系,因为具备的数量几乎都足以在相同布置表上展现;
  2. 好计划实用的目录;

1.2.2 反范式化的缺陷:

  1. 报表内的冗余较多,删除数据时会招表有把生由此之信丢失。

1.2.3 反范式化设计之事例:
因囤一首图书及其作者也条例,作者的信息包括作者的真名,年龄,国籍。使用反范式化的宏图如下:

{
      "_id" : ObjectId("5124b5d86041c7dca81917"),
      "title" : "如何使用MongoDB",
      "author" : [
               {
                        "name" : "丁磊"
                        "age" : 40,
                        "nationality" : "china",
               },
               {
                        "name" : "马云"
                        "age" : 49,
                        "nationality" : "china",
               },
               {
                        "name" : "张召忠"
                        "age" : 59,
                        "nationality" : "china",
               },
     ]
}     

以斯示例中大家将作者的字段完全搭到了书籍被失去,在询问的时节一向询问图书即可获所对应作者的通音讯,但以一个作者或爆发差不多照小说,当修改某位作者的音讯时,我们要遍历所有书籍为搜寻到该作者,将该修改。

鉴于用于封装错误音信之要命细节类型的目的末了要经过信息交换的法自服务端传播到客户端,所以该对象假若一个可是体系化的目的。WCF通过简单栽典型体系化器实现对数码对象的体系化和倒连串化,其中一个凡是人情的System.Xml.Serialization.XmlSerializer,该队换器被ASP.NET
Web服务用于对象同XML之间的序列化和倒体系化;另一个虽是System.Runtime.Serialization.DataContractSerializer,用于因数契约对象的连串化和倒连串化,后者是WCF默认采取的连串化器。所以,可系列化的一无是处明细类型一般是一个多少契约,或者是一个使了System.SerializableAttribute特性的品种。关于系列化,和与此相关的数码契约、数据契约体系化器等,在《WCF技术分析(卷1)》的第5节来深切、周到的牵线。

3.1 索引颗粒越少越好

啊让颗粒越小越好?在索引列中每个数据的更数量称为颗粒,也于作索引的基数。假使数量的微粒过好,索引就无法发挥该有的特性。例如,大家拥有一个”age”列索引,倘诺在”age”列中,20东占了50%,如若现在如询问一个20春秋,名叫”Tom”的丁,我们则要在表的50%的数据中询问,索引的意向大大降低。所以,我们在确立目录时假设尽量以数据颗粒小之列放在目录左侧,以保证索引发挥最好可怜之来意。

总的看,上述的这么些契约基本上依然绕在一个正常化劳动调用下之消息交流:服务之主顾通过奔劳动的提供者发送请求音信,服务之提供者在收受到拖欠要后,激活服务实例并调用相应的服务操作,最后用回到的结果为平复音信的章程赶回给劳务之主顾(对于One-way,则无需要信息的死灰复燃)。可是,假设服务操作不可知是地履,服务端将会因此平等种特有之信息将错误消息重回给客户端,这种音信被称错误音信(Fault
Message)。对于错误消息,同样要相应的契约来定义其布局,我们拿这种契约称为错误契约(Fault
Contract)。

二. 填充因子的利用

填充因子(padding
factor)是MongoDB为文档的恢弘而留给的滋长空间,因为MongoDB的文档是为顺序表的方囤的,每个文档中会异常严格。
填充因子的了然之所以要,是坐文档的运动异常耗性能,频繁的活动会大大扩大系统的负,在实质上支付中分外有或相会吃文档体积变死之要素是累组,所以假诺大家的文档会频繁修改并附加空间吧,则早晚要丰盛考虑填充因子。

则以多景下,在服务端指定服务操作的长河遭到一向丢掉来含有自定义错误音讯的FaultException分外,就会过客户端感知到碰到的现实错误并举行必要的排错和纠错。不过,大家再一次多地,如故倾向被直接定义一个门类来描述良音讯。我个人倾向被这样同样近似的色也左明细类型(Fault
Detail
Type)。服务端依照现实的怪现象创制相应的一无是处类型对象,并冲该目的大家地方提到的System.ServiceModel.FaultException<TDetail>相当,其中泛型类型参数为深细节类型。在此过程被,还提到到一个要之概念:错误契约(Fault
Contract),接下去,大家即便来介绍一下FaultException<TDetail>和错误契约。

四. 尾声

本文首要参照了以下简单篇博文:

  1. http://www.cnblogs.com/mokafamily/p/4102829.html
  2. http://blog.csdn.net/puqutogether/article/details/45650963

通过WCF基本的百般处理形式[上篇]
我们清楚了:在默认的情况下,服务端在实践有服务操作时抛来之不得了(在此处指非FaultException非常),其休戚相关的错误新闻仅仅限于服务端可见,并无谋面被WCF传递至客户端;即便用打开了IncludeExceptionDetailInFaults的Service(Service)Debug服务行为经过注明(通过在服务类型上拔取瑟维斯(Service)BehaviorAttrite特性)或者配置的主意利用至相应的劳务达到,十分系的持有细节音讯以会原本封不动地奔客户端传送。

1.3 范式化与反范式化混用

为了兼顾范式化与相反范式化的利弊,经常比常使范式化与反范式化混合使用的模式,混合范式化与相反范式化的宏图如下:

{
      "_id" : ObjectId("5124b5d86041c7dca81917"),
      "title" : "如何使用MongoDB",
      "author" : [ 
              {
                        "_id" : ObjectId("144b5d83041c7dca84416"),
                        "name" : "丁磊"
               },
               {
                        "_id" : ObjectId("144b5d83041c7dca84418"),
                        "name" : "马云"
               },
               {
                        "_id" : ObjectId("144b5d83041c7dca84420"),
                        "name" : "张召忠"
               },
     ]
} 

这种艺术是平种争持折中之主意,既保证了查询功用,也准保的翻新频率。但这么的方明确要较前片栽于难以精晓,难点在于要以及实际工作举行组合来寻觅合适的领取字段。

客户端服务调用相关的可怜处理为作如下相应的改:

2.1 常用的有限种模式

2.1.1 扩充起始分配空间
每当会聚的性被蕴藏一个 usePowerOf2Sizes
属性,当这选项也true时,系统会将后续插入的文档,开端空间都分配也2底N次方。
这种分配机制适用于一个数据会频繁变动的集结使用,他会见为每个文档留有重可怜的半空中,但因故空间的分配不会师像原来这样便捷,如若你的聚众在革新时莫会合频之出现活动现象,这种分配办法会造成写副速度相对变慢。

2.1.2 利用数据强行将启分配空间扩充

db.book.insert({
   "name" : "MongoDB",
   "publishing" : "清华大学出版社",
   "author" : "john",
   "tags" : [],
   "stuff" : "ggggggggggggggggggggggggggggggggggggg
              ggggggggggggggggggggggggggggggggggggg
              ggggggggggggggggggggggggggggggggggggg"
})

然看起或未顶优雅,但偶尔却大实惠!当大家针对斯文档举办增长式修改时,只要拿stuff字段删掉即可。当然,这多少个stuff字段随便你怎么起名,包括内部的填充字符当然为是足以肆意添加的。

   1: using System.ServiceModel;

   2: using Artech.WcfServices.Contracts;

   3: namespace Artech.WcfServices.Services

   4: {

   5:     public class CalculatorService : ICalculator

   6:     {

   7:         public int Divide(int x, int y)

   8:         {

   9:             if (0 == y)

  10:             {

  11:                 throw new FaultException<string>("被除数y不能为零!", "被除数y不能为零!");

  12:             }

  13:             return x / y;

  14:         }

  15: }

  16: }

一. 范式化与反范式化

范式是为着免去再数据减弱冗余数据,从而让数据库内之多少重复好的协会,让磁盘空间得到更使得采纳的一律栽口径标准,知足高等级的范式的先决条件是满意低等级范式。在数据库设计阶段,明确集合的用是对mongodb数据库性能调优十分关键之平等步。依据集合中数量最常用的操作,对于频繁更新与高频查询的汇聚,大家最好亟需关怀的严重性是她们之范式化程度。

   1: using System;

   2: using System.ServiceModel;

   3: using Artech.WcfServices.Contracts;

   4: namespace Artech.WcfServices.Clients

   5: {

   6:     class Program

   7:     {

   8:         static void Main(string[] args)

   9:         {

  10:             using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>(

  11:                "calculatorservice"))

  12:             {

  13:                 ICalculator calculator = channelFactory.CreateChannel();

  14:                 using (calculator as IDisposable)

  15:                 {

  16:                     try

  17:                     {

  18:                         int result = calculator.Divide(1, 0);

  19:                     }

  20:                     catch (FaultException ex)

  21:                     {

  22:                         Console.WriteLine(ex.Message);

  23:                         (calculator as ICommunicationObject).Abort();

  24:                     }

  25:                 }

  26:             }

  27:         }

  28:     }

  29: }

1.1 范式化

1.1.1 范式化的优点:

  1. 范式化的数据库更新起来再也加快;
  2. 范式化之后,只来大少之再一次数据,只需要修改更少之数量;
  3. 范式化的申还粗,能够于内存中实施;
  4. 可怜少之冗余数据,在查询的时用再行少之distinct或者group by语句。

1.1.2 范式化的短处:

  1. 范式化的表达,在询问的时候通常需要广大之关联,因为单独一个表内不有冗余和还数据。这导致,稍微复杂一些底查询语句以查询范式的schema上都可能需要比多次底涉。这会追加被查询的代价,也说不定要有目录策略无效。因为范式化将列存放在不同的表中,而这个列于一个评释中以得以属于同一个目录。

1.1.3 范式化设计的例子:
为囤一首图书及其作者吧条例,作者的信包括作者的真名,年龄,国籍。使用范式化的筹划如下:

{
    "_id" : ObjectId("5124b5d86041c7dca81917"),
    "title" : "如何使用MongoDB", 
    "author" : [ 
             ObjectId("144b5d83041c7dca84416"),
             ObjectId("144b5d83041c7dca84418"),
             ObjectId("144b5d83041c7dca84420"),
    ]
}

以作者(comment)
的id数组作为一个字段添加到了图书中错过。这样的设计方是于非关系型数据库被常用的。在MongoDB中我们以和主键没有直接关联之撰稿人详细音信单独提取到任何一个汇,用存储主键的措施展开关联查询。当我们而查询著作与作者时需先查询及所要的篇章,再打著作作者中获作者id,最终得的一体化的章及其作者详细音信。在这种状态下询问性能显著是未完美之,因为急需举行比多的干查询。但当某位作者的音用改时,范式化的爱惜优势就是突显出了,我们无需考虑那作者提到的书,直接举行修改是作者的字段即可。

对推行服务操作着丢掉来之异常,假使服务之定义者仅仅要服务之调用者拿到相同截从定义的错误音讯文本(字符串),大家若召开的实在很粗略:在劳务操作中直接抛来一个FaultException分外,该大对象通过为字符串格局反映的自定义错误音信成立。下边的代码中,CalculaorService的Divide情势在指定的时候针对第二参数举行了求证,倘若也零则创制一个FaultException,并点名错误信息(“被除数y不能啊零星!”)。

1.4 总结

  1. 范式化的更新频率是高的,但询问成效是低于的;
  2. 倒范式化的询问效率最高,但革新频率低;
  3. 当其实的工作负我们得依据自己实在的要来计划表中的字段,以博取最高的功用。

起名 1

3.1 索引越少越好

目录可以极大地进步查询性能,那么索引是匪是越多越好?答案是否认的,并且索引并非越多越好,而是更加少越好。每当你建一个目录时,系统会为卿上加一个索引表,用于索引指定的排,但是当你针对已经建立目录的排列举办插队或改动时,数据库则要针对原本的索引表举行再一次排序,重新排序的历程卓殊耗性能,但应针对少量之目录压力并无是非常要命,但如若索引的多寡比多的语句对于性的熏陶显而易见。所以于创设索引时需要审慎建立目录,要将每个索引的机能都要表达到最致,也就是说在可以知足索引需求的情况下,索引的数额越来越少越好。

于大家眼前的例子,当客户端调用CalculatorService(Service)的Divide操作实施除法预算,并传到零看作被除数,服务端将会合扔来FaultException<CalculationError>相当。WCF服务端框架将会见暴发一个Fault
Message,并将连串化后底CalculationError对象作为不当明细放置到Fault
Message的关键性有。假诺下的音讯版本是Soap12Addressing10,即SOAP
1.2暨WS-Addressing 1.0,最后生成的Fault Message将会面要上边的XML片断所示:

三. 索引的用

目对于一个数据库的熏陶相信我们自然通晓,尽管一个询问命令进入及数据库中晚,查询优化器没有找到合适的目录,那么数据库会展开全集合扫描(在RDBMS中吗深受全表扫描),全集合查询对于性的影响是惨痛的。没有索引的查询就似在词典这不用规律的雅量词汇吃赢得某你想假使之词汇,但这词典是绝非目录的,只可以通过逐页来寻找。这样的寻可能会师为你消耗几单刻钟的大运,但假诺要求而询问词汇的频率如同用户访问的效能一样的口舌。。。嘿嘿,我信任你一定会惊呼“老子不关乎了!”。分明总结机不会晤这么喝,它直接是一个早出晚归的员工,不论多苛刻的伸手他还会面好。所以恳请通过索引善待你的电脑。但用索引有些许点用小心:1.
索引起越少越好;2. 索引起颗粒越少越好。

老三、错误契约(Fault Contract)

  • Action:和一般的SOAP音讯无异于,对于Fault
    SOAP,WS-Address报头Action是要的,该属性控制Action报头的价。如若Action属性没有当行使FaultContractAttribute时显式指定,那么它们以依下面的平整举行点名:{服务契约命名空间}/{服务契约名称}/{操作契约名称}{明细类型名称}Fault;
  • DetailType:否即是点所介绍的用来封装错误音信之不当明细类型,比如我们前定义的CalculationError;
  • Name和Namespace:以终极之Fault
    SOAP中,错误明细对象被列化成的XML将会师为置于Fault
    SOAP的重心部分,而当时有限单属性则用来控制就段XML片断对应的称呼及命名空间;假使这半个属性并未作显式设置,WCF将汇合使DetailType对应之数契约名称与命名空间;
  • HasProtectionLevel和ProtectionLevel:当即半单特性涉及到保安级别,属于安全(Security)的题材,在这里就是无多作介绍了。
   1: using System;

   2: using System.Runtime.Serialization;

   3: namespace Artech.WcfServices.Contracts

   4: {

   5:     [DataContractAttribute(Namespace="http://www.artech.com/")]

   6:     public class CalculationError

   7:     {

   8:         public CalculationError(string operation,string message)

   9:         {

  10:             if (string.IsNullOrEmpty(operation))

  11:             {

  12:                 throw new ArgumentNullException("operation");

  13:             }

  14:             if (string.IsNullOrEmpty(message))

  15:             {

  16:                 throw new ArgumentNullException("message");

  17:             }

  18:             this.Operation = operation;

  19:             this.Message = message;

  20:         }

  21:         [DataMember]

  22:         public string Operation

  23:         { get; set; }

  24:         [DataMember]

  25:         public string Message

  26:         { get; set; }

  27:     }

  28: }

起名,在这种情状下,你要开的仍旧是以对应的操作上边,通过动FaultContractAttribute特性指定String类型作为那些DetailType,如上面的代码所示:

按部就班大家在面提到的关于Action、Name和Namespace的默认设定,下面这段代码和下的代码是截然同的。

万一应对下边出错的故,就得讲到WCF或者SOA一个从的风味:服务的提供者和买主中利用基于“契约(Contract)”的交互格局。不同让面向服务,在面向组件设计着,组件之间的互相实际上是因项目标,交互双方需要共享相同档次集(接口、抽象类或者具体类等)。在《WCF技术分析(卷1)》中,大家曾数针对性契约举办了深切的探讨。从空洞层面上讲话,契约时相互双方依然多方就某个平等问题上的同种植共识,使担保正常交互指定的同样多级的规范。

而咱的客户端程序并无可以以我们贯彻预期的这样正常运作,而会丢来而图1所突显之无被处理的FaultException异常,而我辈总括捕获的不可开交类型为FaultException<CalculationError>。

FaultContractAttribute的6只属性分别装有如下的义:

   1: using System.ServiceModel;

   2: namespace Artech.WcfServices.Contracts

   3: {

   4:     [ServiceContract(Namespace = "http://www.artech.com/")]

   5:     public interface ICalculator

   6:     {

   7:         [OperationContract]

   8:         [FaultContract(typeof(string))]

   9:         int Divide(int x, int y);

  10:     }   

  11: }

我们依然用我们地点提到的盘算服务来比喻,现在大家用定义一个独门的花色来描述基于CalculatorService(Service)的老大,大家简直用欠项目起名为CalculationError。我们用CalculationError定义成一个用了System.Runtime.Serialization.DataContractAttribute特征的数契约,简单起见,大家仅仅定义了有限独数据成员(应用了System.Runtime.Serialization.DataMemberAttribute特性):Operation代表造成大相应的演算操作(我们假如CalculatorService具有相同多样运算操作,即使咱的例子中仅仅为起为同一一个除法运算操作:Divide),而Message表述具体的左信息。CalculationError的定义在吃客户端(Client项目)和劳务(Services项目)引用的契约(Contracts项目)中,具体定义如下:

于错误契约的行使,还有少数急需特地说明:不仅仅是以于定义之荒唐明细类型(比如CalculationError)应用到相应的操作契约上,你用显失地利用FaultContractAttribute特性将那一个下及劳动契约接口或者类中相应的操作方法上边,对于部分基元类型,比如Int32,String等,你也要如此。也就是凡是说,同样对我们的盘算服务之例子,假如服务端试图通过撤消来一个FaultException<string>来供错误(如下面的代码所示),客户端最后捕获到之唯有是一个FaultException卓殊,而非FaultException<string>分外。

   1: using System.ServiceModel;

   2: namespace Artech.WcfServices.Contracts

   3: {

   4:     [ServiceContract(Namespace = "http://www.artech.com/")]

   5:     public interface ICalculator

   6:     {

   7:         [OperationContract]

   8:         [FaultContract(typeof(CalculationError))]

   9:         int Divide(int x, int y);

  10:     }   

  11: }

打精神上说话,服务契约(瑟维斯(Service)(Service) Contract)中的诸一个操作契约(Operation
Contract),定义了WCF为落实该服务操作的调用采取的音互换模式(MEP:Message
Exchange
Pattern),并且做基于参数、再次回到值类型的数量契约、音信契约定义了央信息及还原信息的社团(Schema)。数据契约建立了针对平数量的有限种不同表现格局(托管对象和XML)之间的双向适配,以利承载相同消息的多寡在片种植不同造型之间的变,即行换和反连串化。而音信契约在概念了托管对象的顺序成员及相应的音元素中的非凡关系。借助于音讯契约,在针对一个托管对象举行体系化并转移音讯之时段,可以有效地操纵某一个多少成员(属性或者字段)被排化成的XML应该放权音信报头(Header)如故信息主体(Body)。

   1: using System;

   2: using System.ServiceModel;

   3: using Artech.WcfServices.Contracts;

   4: namespace Artech.WcfServices.Clients

   5: {

   6:     class Program

   7:     {

   8:         static void Main(string[] args)

   9:         {

  10:             using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>(

  11:                "calculatorservice"))

  12:             {

  13:                 ICalculator calculator = channelFactory.CreateChannel();

  14:                 using (calculator as IDisposable)

  15:                 {

  16:                     try

  17:                     {

  18:                         int result = calculator.Divide(1, 0);

  19:                     }

  20:                     catch (FaultException<CalculationError> ex)

  21:                     {

  22:                         Console.WriteLine("运算错误");

  23:                         Console.WriteLine("运算操作:{0}",ex.Detail.Operation);

  24:                         Console.WriteLine("错误消息:{0}",ex.Detail.Message);

  25:                         (calculator as ICommunicationObject).Abort();

  26:                     }

  27:                 }

  28:             }

  29:         }

  30:     }

  31: }
   1: using System.ServiceModel;

   2: namespace Artech.WcfServices.Contracts

   3: {

   4:     [ServiceContract(Name="ICalculator",Namespace = "http://www.artech.com/")]

   5:     public interface ICalculator

   6:     {

   7:         [OperationContract(Name="Divide")]

   8:         [FaultContract(typeof(CalculationError), 

   9:             Action = "http://www.artech.com/ICalculator/DivideCalculationErrorFault",

  10:             Name = "CalculationError", Namespace = "http://www.artech.com/")]

  11:         int Divide(int x, int y);

  12:     }  

  13: }

脚的代码中,大家经过FaultContractAttribute将大家定义错误明细类型CalculationError应用至Divide操作之上,那样的话,大家的例证就是可知健康运转了。

即半栽办法显示了有限种植最的百般传播(Exception
Propagation)机制,对于冲服务操作实施过程遭到丢掉来底充分的缪细节,要么完全对客户端屏蔽,要么全体露被客户端。在真通过WCF来架构我们的分布式系统中,我们累需要同种折中之可怜传播机制:自定义服务端分外信息。这样既能够让客户端取一个善精晓的错误消息,又在定水准达避免了片快信息的泄漏。

WCF通过System.Service(Service)Model.FaultContractAttribute特性定义,由于错误契约是基于服务操作级别之,所以该特性直接接纳被劳动契约接口或者类的操作契约方法成员及。下边的代码片断突显了FaultContractAttribute的定义:

受除数y不克啊零星!

   1: <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">

   2:   <s:Header>

   3:     <a:Action s:mustUnderstand="1">http://www.artech.com/ICalculator/DivideCalculationErrorFault</a:Action>    <a:RelatesTo>urn:uuid:3498ba2d-edd0-4d3b-ba4a-9b35327b5fa3</a:RelatesTo>

   4:   </s:Header>

   5:   <s:Body>

   6:     <s:Fault>

   7:       <s:Code>

   8:         <s:Value>s:Sender</s:Value>

   9:       </s:Code>

  10:       <s:Reason>

  11:         <s:Text xml:lang="zh-CN">被除数y不能为零!</s:Text>

  12:       </s:Reason>

  13:       <s:Detail>

  14:         <CalculationError xmlns="http://www.artech.com/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">

  15:           <Message>被除数y不能为零!</Message>

  16:           <Operation>Divide</Operation>

  17:         </CalculationError>

  18:       </s:Detail>

  19:     </s:Fault>

  20:   </s:Body>

  21: </s:Envelope>

客户端在调用该服务操作的当儿,即使传入零作为为除数,将会合一贯破获服务端定义之抛开来的这么些异常(实际上,这间更了怪对象的体系化、音信交流与那么些对象的反连串化等同样多元之操作)。客户端具体的老大捕获情形假使下边的次序突显:

荒谬契约作为服务描述的均等组成部分,会与届描述服务的第一数据(Metadata)中。当服务元数据经过WSDL的款型让发布的时候,作为针对操作的描述的错契约体现于WSDL的<wsdl:portType>/<wsdl:operation>/<wsdl:fault>节点。下边一段落XML代表Calculator瑟维斯(Service)的WDSL:

一致、 通过FaultException直接指定错误音讯

出口结果:

图1 客户端不可能正常捕获FaultException<CalculationError>异常

   1: [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]

   2: public sealed class FaultContractAttribute : Attribute

   3: {    

   4:     public FaultContractAttribute(Type detailType);

   5:     public string Action { get; set; }

   6:     public Type DetailType { get; }

   7:     public bool HasProtectionLevel { get; }

   8:     public string Name { get; set; }

   9:     public string Namespace { get; set; }

  10:     public ProtectionLevel ProtectionLevel { get; set; }

  11: }
   1: using System.ServiceModel;

   2: using Artech.WcfServices.Contracts;

   3: namespace Artech.WcfServices.Services

   4: {

   5:     public class CalculatorService : ICalculator

   6:     {

   7:         public int Divide(int x, int y)

   8:         {

   9:             if (0 == y)

  10:             {

  11:                 var error = new CalculationError("Divide", "被除数y不能为零!");

  12:                 throw new FaultException<CalculationError>(error,error.Message);

  13:             }

  14:             return x / y;

  15:         }

  16:     }

  17: }
   1: <?xml version="1.0" encoding="utf-8"?>

   2: <wsdl:definitions name="CalculatorService" targetNamespace="http://www.artech.com/" >

   3:   <wsdl:import namespace="http://tempuri.org/" location="http://127.0.0.1:3721/calculatorservice/mex?wsdl=wsdl0"/>

   4:   <wsdl:types>

   5:     <xs:schema elementFormDefault="qualified" targetNamespace="http://www.artech.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.artech.com/">

   6:       <xs:element name="Divide">

   7:         <xs:complexType>

   8:           <xs:sequence>

   9:             <xs:element minOccurs="0" name="x" type="xs:int"/>

  10:             <xs:element minOccurs="0" name="y" type="xs:int"/>

  11:           </xs:sequence>

  12:         </xs:complexType>

  13:       </xs:element>

  14:       <xs:element name="DivideResponse">

  15:         <xs:complexType>

  16:           <xs:sequence>

  17:             <xs:element minOccurs="0" name="DivideResult" type="xs:int"/>

  18:           </xs:sequence>

  19:         </xs:complexType>

  20:       </xs:element>

  21:       <xs:complexType name="CalculationError">

  22:         <xs:sequence>

  23:           <xs:element minOccurs="0" name="Message" nillable="true" type="xs:string"/>

  24:           <xs:element minOccurs="0" name="Operation" nillable="true" type="xs:string"/>

  25:         </xs:sequence>

  26:       </xs:complexType>

  27:       <xs:element name="CalculationError" nillable="true" type="tns:CalculationError"/>

  28:     </xs:schema>

  29:   </wsdl:types>

  30:   <wsdl:message name="ICalculator_Divide_InputMessage">

  31:     <wsdl:part name="parameters" element="tns:Divide"/>

  32:   </wsdl:message>

  33:   <wsdl:message name="ICalculator_Divide_OutputMessage">

  34:     <wsdl:part name="parameters" element="tns:DivideResponse"/>

  35:   </wsdl:message>

  36:   <wsdl:message name="ICalculator_Divide_CalculationErrorFault_FaultMessage">

  37:     <wsdl:part name="detail" element="tns:CalculationError"/>

  38:   </wsdl:message>

  39:   <wsdl:portType name="ICalculator">

  40:     <wsdl:operation name="Divide">

  41:       <wsdl:input wsaw:Action="http://www.artech.com/ICalculator/Divide" message="tns:ICalculator_Divide_InputMessage"/>

  42:       <wsdl:output wsaw:Action="http://www.artech.com/ICalculator/DivideResponse" message="tns:ICalculator_Divide_OutputMessage"/>

  43:       <wsdl:fault wsaw:Action="http://www.artech.com/ICalculator/DivideCalculationErrorFault" name="CalculationErrorFault" message="tns:ICalculator_Divide_CalculationErrorFault_FaultMessage"/>

  44:     </wsdl:operation>

  45:   </wsdl:portType>

  46:   <wsdl:service name="CalculatorService">

  47:     <wsdl:port name="CustomBinding_ICalculator" binding="i0:CustomBinding_ICalculator">

  48:       <soap12:address location="http://127.0.0.1:3721/calculatorservice"/>

  49:       <wsa10:EndpointReference>        <wsa10:Address>http://127.0.0.1:3721/calculatorservice</wsa10:Address>

  50:       </wsa10:EndpointReference>

  51:     </wsdl:port>

  52:   </wsdl:service>

  53: </wsdl:definitions>

仲、 通过FaultException<TDetail>接纳打定义类型封装错误

自打FaultContractAttribute的概念大家可以看出,该特性可当与一个对象靶方面往往运(AllowMultiple

true)。这为老好明:对于与一个劳务操作,可能装有不同的这个现象,在不同之气象下,需要抛出不同之要命。

   1: [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]

   2: public sealed class FaultContractAttribute : Attribute

   3: {    

   4:     //省略成员

   5: }

而,若是你于同一个操作方法下边运用了大半了FaultContractAttribute特性的下,需要以相同多元之平整,我们将在《WCF基本好处理形式(下篇)》中举办逐一介绍。

作者:Artech
出处:http://artech.cnblogs.com
本文版权归作者和果壳网共有,欢迎转载,但未经作者同意要保留这么些段子阐明,且以篇章页面分明地方为有原文连接,否则保留追究法律责任的义务。

   1: using System.ServiceModel;

   2: using Artech.WcfServices.Contracts;

   3: namespace Artech.WcfServices.Services

   4: {

   5:     [ServiceBehavior(IncludeExceptionDetailInFaults = true)]

   6:     public class CalculatorService : ICalculator

   7:     {

   8:         public int Divide(int x, int y)

   9:         {

  10:             if (0 == y)

  11:             {

  12:                 throw new FaultException("被除数y不能为零!");

  13:             }

  14:             return x / y;

  15:         }

  16:     }

  17: }

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图