06 WCF契约服务行为和异常处理

一、WCF契约服务行为

  【1】
  服务行为可以修改和控制WCF服务的运行特性。
  在实现了WCF服务契约后,可以修改服务的很多执行特性。
  这些行为(或者特性)是通过配置运行时属性或者通过自定义行为来控制的。

【2】分类

  WCF的行为分为两类:

    服务行为(Service Behavior)

    操作行为(Operation Behavior)

【3】应用的位置

应用在实现接口的类上,而不是接口上。

[ServiceBehavior]
public class ServiceClass:IService1
{
[OperationBehavior]
public int AddNumber(int x,int y)
{
return x+y;
}

  【4】服务的行为配置有两种方式:

  【4-1】使用代码配置

示例:在宿主中,使用 

ServiceHost的Description.Behaviors.Add()方法
            //地址
Uri pipeaddress = new Uri("net.pipe://localhost/NetNamedPipeBinding");
Uri tcpaddress = new Uri("net.tcp://localhost:8088/TcpBinding");
。。。
//服务宿主对象
host = new ServiceHost(typeof(WcfServiceLibrary1.Service1), pipeaddress, tcpaddress);
。。。
//添加元数据 行为
ServiceMetadataBehavior mBehavior = new ServiceMetadataBehavior();
host.Description.Behaviors.Add(mBehavior);

或者是:

[ServiceBehavior]
public class ServiceClass:IService1
{
[OperationBehavior]
public int AddNumber(int x,int y)
{
return x+y;
}
[OperationBehavior]
public int SubtractNumber(int x,int y)
{
return x-y;
}
}

  【4-2】使用配置文件配置

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="WcfServiceLibrary1.Service1" behaviorConfiguration="textBehavior">
。。。。。。
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="textBehavior">
<serviceMetadata/>
<serviceDebug/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

【5】[ServiceBehavior]的属性

AutomaticSessionShutdown                     客户端关闭会话时服务是否自动关闭
ConcurrencyMode 线程的支持,默认:服务是单线程
IgnoreExtensionDataObject 跟序列化有关
IncludeExceptionDetaillnFaults 如何处理未被处理的异常
InstanceContextMode 服务实例对象创建的模式,PerCall 表示每次来一个请求为其创建一个对象的实例,调用后回收;PerSession是每次一个请求来只创建一个该服 务对象的实例直至其销毁,调用后进行回收,并且会话间不能共享; Single表示只允许创建一个该服务的实例,调用后不回收
ReleaseServiceInstanceOnTransactionComplete
TransactionAutoCompleteOnSessionClose
TransactionlsolationLevel
TtansactionTimeout
AutoDisposeParameters
ReleaseInstanceMode 操作完后回收对象、调用操作前回收、根据自动方式回收
TransactionAutoComplete 使用自动提交事务,默认为true

一个配示例:

 <system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="unity" type="ByteartRetail.Infrastructure.UnityExtensions.UnityBehaviorExtensionElement, ByteartRetail.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<unity operationContextEnabled="true" instanceContextEnabled="true" contextChannelEnabled="true" serviceHostBaseEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>

另一个:

 <serviceBehaviors>
<behavior name="WcfService1.Service1Behavior">
<serviceAuthorization ></serviceAuthorization>
<serviceTimeouts/>
<serviceThrottling maxConcurrentCalls="" maxConcurrentInstances="" maxConcurrentSessions=""/>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>

二、异常处理

  【1】种类:

    FaultException                创建非类型化的错误,在服务端进行创建,然后用SOAP方式返回客户端

TimeoutException

           CommunicationException

FaultException异常:

#region 程序集 System.ServiceModel.dll, v4.0.0.0
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.ServiceModel.dll
#endregion using System;
using System.Runtime.Serialization;
using System.Security;
using System.ServiceModel.Channels; namespace System.ServiceModel
{
// 摘要:
// 用于在客户端应用程序中捕获通过协定方式指定的 SOAP 错误。
//
// 类型参数:
// TDetail:
// 可序列化错误详细信息类型。
[Serializable]
public class FaultException<TDetail> : FaultException
{
// 摘要:
// 初始化使用指定详细信息对象的 System.ServiceModel.FaultException<TDetail> 类的新实例。
//
// 参数:
// detail:
// 用作 SOAP 错误详细信息的对象。
public FaultException(TDetail detail);
//
// 摘要:
// 将流反序列化为 System.ServiceModel.FaultException 对象时,使用指定的序列化信息和上下文初始化 System.ServiceModel.FaultException<TDetail>
// 类的新实例。
//
// 参数:
// info:
// 从 context 中重新构造 System.ServiceModel.FaultException 对象时必需的序列化信息。
//
// context:
// 从中重新构造 System.ServiceModel.FaultException 对象的流。
protected FaultException(SerializationInfo info, StreamingContext context);
//
// 摘要:
// 初始化使用指定详细信息对象和错误原因的 System.ServiceModel.FaultException<TDetail> 类的新实例。
//
// 参数:
// detail:
// 用作 SOAP 错误详细信息的对象。
//
// reason:
// SOAP 错误的原因。
public FaultException(TDetail detail, FaultReason reason);
//
// 摘要:
// 初始化使用指定详细信息和错误原因的 System.ServiceModel.FaultException<TDetail> 类的新实例。
//
// 参数:
// detail:
// 用作 SOAP 错误详细信息的对象。
//
// reason:
// SOAP 错误的原因。
public FaultException(TDetail detail, string reason);
//
// 摘要:
// 初始化 System.ServiceModel.FaultException<TDetail> 类的新实例,该类使用指定的详细信息对象、错误原因和错误代码。
//
// 参数:
// detail:
// 用作 SOAP 错误详细信息的对象。
//
// reason:
// SOAP 错误的原因。
//
// code:
// SOAP 错误的错误代码。
public FaultException(TDetail detail, FaultReason reason, FaultCode code);
//
// 摘要:
// 初始化 System.ServiceModel.FaultException<TDetail> 类的新实例,该类使用指定的详细信息对象、错误原因和错误代码。
//
// 参数:
// detail:
// 用作 SOAP 错误详细信息的对象。
//
// reason:
// SOAP 错误的原因。
//
// code:
// SOAP 错误的错误代码。
public FaultException(TDetail detail, string reason, FaultCode code);
//
// 摘要:
// 初始化 System.ServiceModel.FaultException<TDetail> 类的新实例,该类使用指定的详细信息对象以及 SOAP
// 错误原因、代码和操作值。
//
// 参数:
// detail:
// 用作 SOAP 错误详细信息的对象。
//
// reason:
// SOAP 错误的原因。
//
// code:
// SOAP 错误的错误代码。
//
// action:
// SOAP 错误的操作。
public FaultException(TDetail detail, FaultReason reason, FaultCode code, string action);
//
// 摘要:
// 初始化 System.ServiceModel.FaultException<TDetail> 类的新实例,该类使用指定的详细信息对象以及 SOAP
// 错误原因、代码和操作值。
//
// 参数:
// detail:
// 用作 SOAP 错误详细信息的对象。
//
// reason:
// SOAP 错误的原因。
//
// code:
// SOAP 错误的错误代码。
//
// action:
// SOAP 错误的操作。
public FaultException(TDetail detail, string reason, FaultCode code, string action); // 摘要:
// 获取包含错误条件详细信息的对象。
//
// 返回结果:
// System.ServiceModel.FaultException<TDetail> 对象的类型参数的详细信息对象。
public TDetail Detail { get; } // 摘要:
// 创建一个 System.ServiceModel.Channels.MessageFault 对象,该对象可用于创建表示 SOAP 错误的 System.ServiceModel.Channels.Message。
//
// 返回结果:
// 创建的错误消息。
public override MessageFault CreateMessageFault();
//
// 摘要:
// 实现在将对象序列化到流中时调用的 System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)
// 方法。
//
// 参数:
// info:
// 序列化时向其添加对象数据的序列化信息。
//
// context:
// 序列化对象的目标。
[SecurityCritical]
public override void GetObjectData(SerializationInfo info, StreamingContext context);
//
// 摘要:
// 返回 System.ServiceModel.FaultException<TDetail> 对象的字符串。
//
// 返回结果:
// SOAP 错误的字符串。
public override string ToString();
}
}

服务端:

    public class Service1 : IService1
{
public void Divide(int x, int y)
{
try
{
int z = x / y;
}
catch(Exception e)
{
throw new FaultException("试图除零",new FaultCode("除法操作"));
}
}
}

客户端:

            server.Service1Client client = new wcfClient.server.Service1Client();

            try
{
client.Divide(, );
client.Abort();
client.Divide(, );
}
catch (FaultException fe)
{
MessageBox.Show(fe.Reason.ToString());
}
catch (TimeoutException te)
{
MessageBox.Show("调用超时");
}
catch (CommunicationException ce)
{
MessageBox.Show("通信异常!");
}

【2】FaultContract:自定义错误信息:FaultData

    // 摘要:
// 指定服务操作遇到处理错误时返回的一个或多个 SOAP 错误。
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
public sealed class FaultContractAttribute : Attribute

使用步骤:

  第一步:

    [ServiceContract(Namespace = "http://www.Keasy5.com")]
public interface IOrderService
{
[OperationContract]
[FaultContract(typeof(FaultData))]
int GetShoppingCartItemCount(Guid userID);

FaultData.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel; namespace Keasy5.DataObject
{
/// <summary>
/// Represents the data to be transferred through the
/// network which contains the fault exception information.
/// </summary>
[DataContract]
public class FaultData
{
#region Public Properties
/// <summary>
/// Gets or sets the message of the fault data.
/// </summary>
[DataMember(Order = )]
public string Message { get; set; }
/// <summary>
/// Gets or sets the full message of the fault data.
/// </summary>
[DataMember(Order = )]
public string FullMessage { get; set; }
/// <summary>
/// Gets or sets the stack trace information of the fault exception.
/// </summary>
[DataMember(Order = )]
public string StackTrace { get; set; }
#endregion #region Public Static Methods
/// <summary>
/// Creates a new instance of <c>FaultData</c> class from the specified <see cref="System.Exception"/> object.
/// </summary>
/// <param name="ex">The <see cref="System.Exception"/> object which carries the error information.</param>
/// <returns>A new instance of <c>FaultData</c> class.</returns>
public static FaultData CreateFromException(Exception ex)
{
return new FaultData
{
Message = ex.Message,
FullMessage = ex.ToString(),
StackTrace = ex.StackTrace
};
}
/// <summary>
/// Creates a new instance of <see cref="FaultReason"/> class from the specified <see cref="Exception"/> object.
/// </summary>
/// <param name="ex">The <see cref="System.Exception"/> object which carries the error information.</param>
/// <returns>A new instance of <see cref="FaultReason"/> class.</returns>
public static FaultReason CreateFaultReason(Exception ex)
{
return new FaultReason(ex.Message);
}
#endregion
}
}

  第二步:

    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“OrderService”。
// 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 OrderService.svc 或 OrderService.svc.cs,然后开始调试。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class OrderService : IOrderService
{
private readonly IOrderService orderServiceImpl = ServiceLocator.Instance.GetService<IOrderService>();
public Int32 GetShoppingCartItemCount(Guid userID)
{
try
{
return orderServiceImpl.GetShoppingCartItemCount(userID);
}
catch (Exception ex)
{
throw new FaultException<FaultData>(FaultData.CreateFromException(ex), FaultData.CreateFaultReason(ex));
}
}

使用了这个构造函数:

        //
// 摘要:
// 初始化使用指定详细信息对象和错误原因的 System.ServiceModel.FaultException<TDetail> 类的新实例。
//
// 参数:
// detail:
// 用作 SOAP 错误详细信息的对象。
//
// reason:
// SOAP 错误的原因。
public FaultException(TDetail detail, FaultReason reason);

【WCF--初入江湖】06 WCF契约服务行为和异常处理的更多相关文章

  1. [SignalR]SignalR与WCF双工模式结合实现服务端数据直推浏览器端

    原文:[SignalR]SignalR与WCF双工模式结合实现服务端数据直推浏览器端 之前开发基于WinForm监控的软件,服务端基于Wcf实现,里面涉及双工模式,在客户端里面,采用心跳包机制保持与服 ...

  2. WCF开发指南之构建服务

    一. 引言 Windows通讯基础(简称为WCF)是一种SDK,用于让你使用典型的CLR编程结构(例如用于发布和消费服务的类和接口等)来构建Windows面向服务的应用程序.WCF的编程模型是声明性的 ...

  3. 关于WCF的引用,添加服务和添加web服务的区别

    原文:关于WCF的引用,添加服务和添加web服务的区别 本章内容主要是根据我做的实验来阐述这2种添加服务针对WCF的不同之处,我们按照示例一步一步来看. 如下是工程的结构: 该WCF服务是通过控制台程 ...

  4. 使用WCF Data Service 创建OData服务

    使用WCF Data Service 创建OData服务 在 上一章 中,介绍了如何通过 OData 协议来访问 OData 服务提供的资源.下面来介绍如何创建一个 OData 服务.在这篇文章中,主 ...

  5. WCF入门(十)——服务对象模型

    当发生一次WCF请求-响应操作时,会经过如下几个步骤 WCF Client想WCF Server发送一个服务请求 WCF Server创建WCF服务对象 WCF Server调用WCF服务对象接口,将 ...

  6. 【WCF】WCF 附录 高级主题 配置服务配额设置

    微软产品自带一个“默认安全”方案.这也包括了WCF,意味着WCF中的多种配置可以设置来阻止诸如DOS(拒绝服务访问)攻击.微软为很多基于一个单一计算机的开发环境选择这样的设置.这也意味着默认设置中的一 ...

  7. 【WCF 1】WCF框架宏观了解

    导读:使用WCF框架爱开发项目也有很长一段时间了,最开始的时候,是理解的不深,所以不写博客进行总结.后来是项目赶,发现需要总结的有很多,一直没有把WCF排上日程,尤其是最近研究EF这一块,更是研究了一 ...

  8. WCF入门一[WCF概述]

    一.什么是WCF WCF是使用托管代码建立和运行面向服务(Service Oriented)应用程序的统一框架.它使得开发者能够建立一个跨平台的.安全.可信赖.事务性的解决方案,且能与已有系统兼容协作 ...

  9. WCF学习笔记——WCF基础

    一 WCF与SOA SOA是一种通过为所有软件提供服务外观,并将这些服务的WSDL集中发布到一个地方的一种组织企业软件的方法.它通过使用明确定义的接口通过跨越边界传递消息来让多个自治的服务协同工作.S ...

随机推荐

  1. C#时间格式 tostring、toshortdatestring、toshorttimestring

    在c#语言中的时间处理有几种方式: 首先获取当前时间:var date=new DateTime.Now; date.ToString()----2111-1-20 11:44:47 date.ToS ...

  2. AMQ学习笔记 - 17. 事务的测试

    概述 对事务机制进行测试. 测试实例 测试实例 结果预测 发送正常 3条消息入队 发送异常 0条消息入队 接收正常 3条消息出队 接收异常 0条消息出队 demo设计 设计图 测试分工 测试类 测试方 ...

  3. Linux 内核同步机制

        本文将就自己对内核同步机制的一些简要理解,做出一份自己的总结文档.     Linux内部,为了提供对共享资源的互斥访问,提供了一系列的方法,下面简要的一一介绍. Technorati 标签: ...

  4. activiti搭建(一)初始化数据库

    转载请注明源地址:http://www.cnblogs.com/lighten/p/5876681.html activiti-engine.jar包中自带了创建activiti工作流数据库表的SQL ...

  5. C#参数化SQL查询

    //写一个存储过程 ALTER PROCEDURE dbo.Infosearch ( @bmid smallint = null, @xm varchar()=null, @xb varchar()= ...

  6. seajs构建方法

    标准构建 如果项目遵循推荐的标准目录结构: foo-module/   |-- dist                    //存放构建好的文件   |-- src                 ...

  7. nginx 日志管理

    日志管理 我们观察nginx的server段,可以看到如下类似信息 #access_log  logs/host.access.log  main; 这说明 该server, 它的访问日志的文件是  ...

  8. js实现雪花飘落效果的代码

    使用js实现雪花飘落的效果,用html5绘布加js写的雪花飘效果 . 代码: <html> <head> <script> /** * js与html5实现的雪花飘 ...

  9. 2013-07-24 IT 要闻速记快想

    ### ========================= ###凡客有闹钟?从凡客的角度来讲,闹钟等工具类应用是为推广品牌和产品服务,通过工具类产品给大众一个对凡客品牌的认知.而选择推出工具类的产品 ...

  10. (转)android底部弹出iOS7风格对话选项框(QQ对话框)--第三方开源--IOS_Dialog_Library

    本文转载于:http://blog.csdn.net/zhangphil/article/details/44940339 完成这个效果的是使用了 IOS_Dialog_Library 下载地址:ht ...