What is the best approach to handle exceptions in WCF service?

后端 未结 4 785
悲&欢浪女
悲&欢浪女 2020-12-04 22:11

I have a WCF service deployed on two or more remote machines and there is a desktop based application that is used by the client to access any wcf service.

T

相关标签:
4条回答
  • 2020-12-04 22:58

    You can definitely catch and handle all exceptions that happen on your service class and turn them into a FaultException or FaultException exception.

    That way, you won't "fault" (or tear down) the communications channel between your client and server.

    Even better approach would be to implement the IErrorHandler interface on your service class that provides a way to globally catch all exceptions as they happen and provide a FaultException instead, that's SOAP compliant.

    You can even turn your IErrorHandler into a configurable behavior that can be turned on or off in config.

    See these articles and blog posts for more details:

    • Rory Primrose: Implementing IErrorHandler
    • Useful WCF behaviors: IErrorHandler
    0 讨论(0)
  • 2020-12-04 23:02
    1. Create a custom fault class that is marked with the DataContract attribute
    2. Mark the method on the service contract interface with FaultContract. Ie. [FaultContract(typeof(CustomFault))]
    3. In your service method, catch any applicable internal exceptions and throw a FaultException<CustomFault>. Alternatively, as marc_s mentioned, you can use IErrorHandler to map the exception to the fault.

    Personally, I create a base Fault class that has a Reason property and I extend all custom faults from this class. When I want to throw the fault, I call:

    throw Fault.Create<CustomFault>(new CustomFault("Boo hoo"));
    

    It's also worth noting that I version my fault classes (including the common Fault class) along with all my other services. This is only a concern if service versioning is a concern, though.

    Here's the basic Fault class (I've removed argument validation for brevity):

    [DataContract(Namespace = XmlVersionNamespace.FaultNamespace)]
    public abstract class Fault
    {
        internal FaultReason Reason { get; set; }
    
        protected Fault(string reasonText)
        {
            Reason = new FaultReason(new FaultReasonText(reasonText, CultureInfo.CurrentUICulture));
        }
    
        public override string ToString()
        {
            return Reason.ToString();
        }
    
        internal static FaultException<TDetail> Create<TDetail>(TDetail fault) where TDetail : Fault
        {
            return new FaultException<TDetail>(fault, fault.Reason);
        }
    }
    
    0 讨论(0)
  • 2020-12-04 23:09

    You can design the specific Fault Data Contracts for each of the exception scenario in your WCF service so that you can handle the fault/exception at client side respectively.

    0 讨论(0)
  • 2020-12-04 23:11
    try
    {
      // Actions
    }
    catch (Exception ex)
    {
      // Log the exception
      // Throw Fault Exception back to client
      FaultException fe = new FaultException(ex.Message, new FaultCode("Your fault code"));
      //throw fault exception back to WCF client
      throw fe;
    }           
    
    0 讨论(0)
提交回复
热议问题