• Fault Contract


    The Fault Contract sample demonstrates how to communicate error information from a service to a client. The sample is based on the Getting Started, with some additional code added to the service to convert an internal exception to a fault. The client attempts to perform division by zero to force an error condition on the service.

    Note

    The setup procedure and build instructions for this sample are located at the end of this topic.

    The calculator contract has been modified to include a FaultContractAttribute as shown in the following sample code.

    C#
    [ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]  
    public interface ICalculator  
    {  
        [OperationContract]  
        int Add(int n1, int n2);  
        [OperationContract]  
        int Subtract(int n1, int n2);  
        [OperationContract]  
        int Multiply(int n1, int n2);  
        [OperationContract]  
        [FaultContract(typeof(MathFault))]  
        int Divide(int n1, int n2);  
    }  
    

    The FaultContractAttribute attribute indicates that the Divide operation may return a fault of type MathFault. A fault can be of any type that can be serialized. In this case, the MathFault is a data contract, as follows:

    C#
    [DataContract(Namespace="http://Microsoft.ServiceModel.Samples")]  
    public class MathFault  
    {      
        private string operation;  
        private string problemType;  
      
        [DataMember]  
        public string Operation  
        {  
            get { return operation; }  
            set { operation = value; }  
        }  
      
        [DataMember]          
        public string ProblemType  
        {  
            get { return problemType; }  
            set { problemType = value; }  
        }  
    }  
    

    The Divide method throws a FaultException<TDetail> exception when a divide by zero exception occurs as shown in the following sample code. This exception results in a fault being sent to the client.

    C#
    public int Divide(int n1, int n2)  
    {  
        try  
        {  
            return n1 / n2;  
        }  
        catch (DivideByZeroException)  
        {  
            MathFault mf = new MathFault();  
            mf.operation = "division";  
            mf.problemType = "divide by zero";  
            throw new FaultException<MathFault>(mf);  
        }  
    }  
    

    The client code forces an error by requesting a division by zero. When you run the sample, the operation requests and responses are displayed in the client console window. You see the division by zero being reported as a fault. Press ENTER in the client window to shut down the client.

    console
    Add(15,3) = 18  
    Subtract(145,76) = 69  
    Multiply(9,81) = 729  
    FaultException<MathFault>: Math fault while doing division. Problem: divide by zero  
      
    Press <ENTER> to terminate client.  
    

    The client does this by catching the appropriate FaultException<MathFault> exception:

    C#
    catch (FaultException<MathFault> e)  
    {  
        Console.WriteLine("FaultException<MathFault>: Math fault while doing " + e.Detail.operation + ". Problem: " + e.Detail.problemType);  
        client.Abort();  
    }  
    

    By default, the details of unexpected exceptions are not sent to the client to prevent details of the service implementation from escaping the secure boundary of the service. FaultContract provides a way to describe faults in a contract and mark certain types of exceptions as appropriate for transmission to the client. FaultException<T> provides the run-time mechanism for sending faults to consumers.

    However, it is useful to see the internal details of a service failure when debugging. To turn off the secure behavior previously described, you can indicate that the details of every unhandled exception on the server should be included in the fault that is sent to the client. This is accomplished by setting IncludeExceptionDetailInFaults to true. You can either set it in code, or in configuration as shown in the following sample.

    XML
    <behaviors>  
      <serviceBehaviors>  
        <behavior name="CalculatorServiceBehavior">  
          <serviceMetadata httpGetEnabled="True"/>  
          <serviceDebug includeExceptionDetailInFaults="True" />  
        </behavior>  
      </serviceBehaviors>  
    </behaviors>  
    

    Further, the behavior must be associated with the service by setting the behaviorConfiguration attribute of the service in the configuration file to "CalculatorServiceBehavior".

    To catch such faults on the client, the non-generic FaultException must be caught.

    This behavior should only be used for debugging purposes and should never be enabled in production.

    To set up, build, and run the sample

    1. Ensure that you have performed the One-Time Setup Procedure for the Windows Communication Foundation Samples.

    2. To build the C# or Visual Basic .NET edition of the solution, follow the instructions in Building the Windows Communication Foundation Samples.

    3. To run the sample in a single- or cross-machine configuration, follow the instructions in Running the Windows Communication Foundation Samples.

    Important

    The samples may already be installed on your machine. Check for the following (default) directory before continuing.

    <InstallDrive>:WF_WCF_Samples

    If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows Communication Foundation (WCF) and WF samples. This sample is located in the following directory.

    <InstallDrive>:WF_WCF_SamplesWCFBasicContractServiceFaults

    WCF: can't catch FaultException(TDetail) - only non-generic FaultException

    最后发现,是因为有人在全局的异常处理的地方,实现了IErrorHandler

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
    if(error is FaultException<NameDuplicationFault>) { }
    else
    {
    var faultException = new FaultException(
    "Server error. Detail: " + error.Message);
    var messageFault = faultException.CreateMessageFault();

    fault = Message.CreateMessage(version, messageFault, faultException.Action);
    }
    }

  • 相关阅读:
    时间序列的小波分析
    粒子群算法优化BP生物能神经网络
    day:3.9基础复习
    计算机网络通信基础
    面向对象的补充
    python中的类和对象
    R语言基础
    函数(2)
    python开发第四篇:函数(1)
    Python开发【第三篇】:Python基本数据类型
  • 原文地址:https://www.cnblogs.com/chucklu/p/10955690.html
Copyright © 2020-2023  润新知