WCF服务创建与抛出强类型SOAP Fault

简介:

前面的文章《WCF服务的异常消息》中介绍过,如果WCF Service发生异常时,Service会将异常序列化为SOAP Fault并发送给客户端。

默认情况下,出于安全原因,WCF Service中未处理的异常的详细信息不会包括在发送给客户的SOAP Fault里,你只能看到一个通用的SOAP Fault(“The server was unable to process the request due to an internal error.”)。在调试程序的时候,如果想在SOAP Fault中包含异常的详细信息,可以修改服务器的配置文件。

复制代码
<behaviors>
  <serviceBehaviors>
    <behavior name="includeExceptionDetails">
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>
复制代码


 

SOAP Fault是XML格式,与平台无关。通常一个SOAP Fault包含以下节点

(1) faultcode

(2) faultstring

(3) detail

 

Detail节点可以用来包括自定义XML信息。

 

WCF Service在发生异常时应抛出FaultException或FaultException<T>,而不应该抛出.NET Exception,出于以下两个原因:

(1)未处理的.NET Exception会使服务器与客户端之间的channel变为Fault状态,继而导致client proxy无法使用。

(2).NET Exception只能被.NET平台理解,而FaultException与平台无关。如果想跨平台使用,需要使用FaultException。

 

下面还是以中《WCF服务的异常消息》的例子来分别演示如何抛出与处理FaultException与强类型的FaultException<T>。

 

(一)使用FaultException

IDemoService.cs:

复制代码
using System.ServiceModel;

namespace WCFDemo 
{    
    [ServiceContract(Name = "IDemoService")] 
    public interface IDemoService 
    { 
        [OperationContract]        
        int Divide(int numerator, int denominator); 
    } 
}
复制代码

 

DemoService.cs:

复制代码
using System; 
using System.ServiceModel; 
using System.ServiceModel.Activation;

namespace WCFDemo 
{ 
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
    public class DemoService : IDemoService 
    { 
        public int Divide(int numerator, int denominator) 
        { 
            if (denominator == 0) 
            { 
                throw new FaultException("Denominator cannot be ZERO!", new FaultCode("DivideByZeroFault")); 
            } 
            return numerator / denominator;           
        } 
    } 
}
复制代码

 

client:

复制代码
private void buttonCalculate_Click(object sender, EventArgs e) 
{ 
    try 
    {                
        textBoxResult.Text = demoServiceClient.Divide(Convert.ToInt32(textBoxNumerator.Text), Convert.ToInt32(textBoxDenominator.Text)).ToString(); 
    } 
    catch (FaultException fault) 
    { 
        MessageBox.Show(fault.Code + " - " + fault.Message); 
    } 
}
复制代码

 

 

image

image

 

SOAP Fault XML

复制代码
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
  <s:Body> 
    <s:Fault> 
      <faultcode>s:DivideByZeroFault</faultcode> 
      <faultstring xml:lang="en-US">Denominator cannot be ZERO!</faultstring> 
    </s:Fault> 
  </s:Body> 
</s:Envelope>
复制代码

 

 

(二)使用强类型FaultException<T>

(1)创建一个自定义SOAP Fault类

DivideByZeroFault.cs:

复制代码
using System.Runtime.Serialization;

namespace WCFDemo 
{ 
    [DataContract] 
    public class DivideByZeroFault 
    { 
        [DataMember] 
        public string Error { get; set; }

        [DataMember] 
        public string Detail { get; set; } 
    } 
}
复制代码

 

(2) 在Service方法上使用FaultContractAttribute来指示哪个操作可以使用哪个Fault

IDemoService.cs:

复制代码
using System.ServiceModel;

namespace WCFDemo 
{    
    [ServiceContract(Name = "IDemoService")] 
    public interface IDemoService 
    { 
        [FaultContract(typeof(DivideByZeroFault))] 
        [OperationContract]        
        int Divide(int numerator, int denominator); 
    } 
}
复制代码

 

DemoService.cs:

复制代码
using System; 
using System.ServiceModel; 
using System.ServiceModel.Activation;

namespace WCFDemo 
{ 
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
    public class DemoService : IDemoService 
    { 
        public int Divide(int numerator, int denominator) 
        { 
            try 
            { 
                return numerator / denominator; 
            } 
            catch (DivideByZeroException ex) 
            { 
                DivideByZeroFault fault = new DivideByZeroFault(); 
                fault.Error = ex.Message; 
                fault.Detail = "Denominator cannot be ZERO!"; 
                throw new FaultException<DivideByZeroFault>(fault); 
            } 
        } 
    } 
}
复制代码

 

client:

复制代码
private void buttonCalculate_Click(object sender, EventArgs e) 
{ 
    try 
    {                
        textBoxResult.Text = demoServiceClient.Divide(Convert.ToInt32(textBoxNumerator.Text), Convert.ToInt32(textBoxDenominator.Text)).ToString(); 
    } 
    catch (FaultException<DemoServiceReference.DivideByZeroFault> fault) 
    { 
        MessageBox.Show(fault.Detail.Error + " - " + fault.Detail.Detail); 
    } 
}
复制代码

 

 

image

image

 

返回的SOAP Fault XML:

复制代码
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
  <s:Body> 
    <s:Fault> 
      <faultcode>s:Client</faultcode> 
      <faultstring xml:lang="en-US">The creator of this fault did not specify a Reason.</faultstring> 
      <detail> 
        <DivideByZeroFault xmlns="http://schemas.datacontract.org/2004/07/WCFDemo" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
          <Detail>Denominator cannot be ZERO!</Detail> 
          <Error>Attempted to divide by zero.</Error> 
        </DivideByZeroFault> 
      </detail> 
    </s:Fault> 
  </s:Body> 
</s:Envelope>
复制代码
相关文章
|
前端开发
WCF更新服务引用报错的原因之一
WCF更新服务引用报错的原因之一
|
C# 数据安全/隐私保护
c#如何创建WCF服务到发布(SqlServer版已经验证)
c#如何创建WCF服务到发布(SqlServer版已经验证)
84 0
|
安全 数据库连接 数据库
WCF服务创建到发布(SqlServer版)
在本示例开始之前,让我们先来了解一下什么是wcf? wcf有哪些特点? wcf是一个面向服务编程的综合分层架构。该架构的项层为服务模型层。 使用户用最少的时间和精力建立自己的软件产品和外界通信的模型。它使得开发者能够建立一个跨平台的安全、可信赖、事务性的解决方案。且能与已有系统兼容写作。 简单概括就是:一组数据通信的应用程序开发接口。
133 0
|
C++
WCF基础教程(二)——解析iis8和iis8.5+VS2013发布wcf服务问题
WCF基础教程(二)——解析iis8和iis8.5+VS2013发布wcf服务问题
152 0
WCF基础教程(二)——解析iis8和iis8.5+VS2013发布wcf服务问题
WCF使用纯代码的方式进行服务寄宿
服务寄宿的目的是为了开启一个进程,为WCF服务提供一个运行的环境。通过为服务添加一个或者多个终结点,使之暴露给潜在的服务消费,服务消费者通过匹配的终结点对该服务进行调用,除去上面的两种寄宿方式,还可以以纯代码的方式实现服务的寄宿工作。
905 0
|
Windows
WCF服务寄宿到IIS
一.WCF简介: Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,可以翻译为Windows 通讯开发平台。整合了原有的windows通讯的 .net Remoting,WebService,Socket的机制,并融合有HTTP和FTP的相关技术。
1107 0
WCF服务自我寄宿
WCF服务的寄宿方式 WCF寄宿方式是一种非常灵活的操作,可以寄宿在各种进程之中,常见的寄宿有: IIS服务、Windows服务、Winform程序、控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者方便、高效提供服务调用。
1048 0
|
网络架构
(纯代码)快速创建wcf rest 服务
因为有一个小工具需要和其它的业务对接数据,所以就试一下看能不能弄一个无需配置快速对接的方法出来,百(以)度(讹)过(传)后(讹),最后还是对照wcf配置对象调试出来了: 1.创建WebHttpBinding 2.
1022 0

热门文章

最新文章