WCF/WebService: Interoperable exception handling

2019-04-05 18:31发布

问题:

I understand that WCF will convert an exception into a fault and send it back as a SOAP message, but I was wondering if this is truly interoperable. I guess I'm having a tough time trying to figure out this possible scenario:

  1. Client (Java) calls a WCF Service (LoginService).
  2. Server checks for proper authorization, user authorization fails.
  3. Server throws an UnauthorizedAccessException.
  4. WCF converts this into a Fault somehow. (* - See Below As Well)
  5. Client has to be able to know how to read this Fault.

I guess I'm just having a tough time understanding how this could still be interoperable because it is expecting Java to know how to translate a SOAP Fault that .NET encodes from an UnauthorizedAccessException.

  • Also, how does .NET actually convert the exception to a fault, what goes in as the fault code, name, etc. Some of the things seem to be "duh"s like perhaps the Fault Name is "UnauthorizedAccessException", but I'd rather know for sure than guess.

回答1:

There is no "automatic conversion". WCF will return a fault (I forget which one) when you have an unhandled exception. But since you didn't declare that fault, many, if not most, clients will fail if you return it.

You are meant to define your own faults and to return them instead. Consider:

[DataContract]
public class MySpecialFault
{
    public string MyMessage { get; set; }
}

[ServiceContract]
public interface IMyService
{
    [FaultContract(typeof (MySpecialFault))]
    [OperationContract]
    void MyOperation();
}

public class MyService : IMyService
{
    public void MyOperation()
    {
        try
        {
            // Do something interesting
        }
        catch (SomeExpectedException ex)
        {
            throw new FaultException<MySpecialFault>(
                new MySpecialFault {MyMessage = String.Format("Sorry, but {0}", ex.Message)});
        }
    }
}

Any client capable of handling faults will deal with this. The WSDL will define the fault, and they will see a fault with the Detail element containing a serialized version of the MySpecialFault instance that was sent. They'll be able to read all the properties of that instance.



回答2:

Faults have been part of the SOAP specification since v1.1. They are explained in the SOAP Specification.

It is up to implementations (WCF, Java etc) to ensure that Faults are handled according to the specification.

Since WCF converts FaultExceptions to Faults according to the SOAP specification, FaultExceptions thrown from WCF are interoperable.



回答3:

SOAP faults are interoperable but .Net exception classes are not good to be used in SOAP faults. Instead define your own DataContract class (e.g. AccessFault) and then use it in a FaultContract. see http://msdn.microsoft.com/en-us/library/ms733841.aspx

Whenever there is a UnauthorizedAccessException thrown at service boundary convert it to FaultException. This can be done in several ways like using Microsoft Enterprise Library Exception Handling Block or implementing the IErrorHandler interface.