官术网_书友最值得收藏!

Return custom exception data through FaultContract

In an XML Web Service and WCF service, the server side will return any unhandled exception as SoapFault in the returned message. For WCF service operations, exceptions are returned to the client through two steps:

  • Map exception conditions to custom SOAP faults
  • Services and client send and receive SOAP faults as exceptions

By default, WCF will return the simple error message or complete exception information (including Callstack) as the Fault content. However, sometimes we want to encapsulate the raw exception information or return some user-friendly error to the client side. To support this kind of customized exception-information format, WCF has provided the FaultContract and FaultException features. FaultException is a new exception type that uses Generic to help WCF service encapsulate various kinds of custom error data objects in a unified way. FaultContract is used to formally specify the type of FaultException that will be returned from the target WCF service operation, so that the client consumers can properly handle and parse it.

How to do it...

  1. First, create the custom error type that will be returned to the service client as exception information. The custom error type is defined as a standard DataContract type.
  2. Then, apply the custom error type to the service operation (which will return this custom error type) through a FaultContractAttribute.
  3. The following code shows a sample custom error type and the service operation that applies it:
      [DataContract]
        public class UserFriendlyError
        {
            [DataMember]
            public string Message
            { get;set; }
        }
    
    [ServiceContract]
        public interface ICalcService
        {
            [OperationContract]
            int Divide(int lv, int rv);
    
            [OperationContract]
     [FaultContract(typeof(UserFriendlyError))]
            int DivideWithCustomException(int lv, int rv);
    }
  4. Finally, we need to add our exception handling code in the service operation's implementation and return the custom error type through the FaultException<T> type (see DivideWithCustomException method shown as follows):
    public int Divide(int lv, int rv)
    {
        if (rv == 0) throw new Exception("Divided by Zero is not allowed!");
        return lv / rv;
            }
    
    public int DivideWithCustomException(int lv, int rv)
    {
     if (rv == 0) throw new FaultException<UserFriendlyError>(new UserFriendlyError() { Message = "Divided by Zero is not allowed!" }
     );
        return lv / rv; 
    }

How it works...

The FaultContractAttribute applied on the service operation will make the runtime generate corresponding metadata entries in the WSDL document (as shown in the next screenshot). Thus, the generated client proxy knows how to handle this custom error type.

How it works...

When invoking the operation, we can add code to handle the specific FaultException and get user-friendly error information from the Exception.Detail property.

try
{
     //call the operation with invalid parameter
}
catch (FaultException<UserFriendlyError> fex)
{
     Console.WriteLine("Error: {0}", fex.Detail.Message);
}

If we use Fiddler or message logging to inspect the underlying SOAP message, we can also find the custom error data in XML-serialized format:

How it works...

There's more...

Since the custom error type used by FaultContract supports any valid DataContract type, we can define various kinds of custom exception data content (from simple primitive types to complex nested classes).

See also

  • Generating DataContract from XML Schema
  • Capturing a WCF request/response message via Fiddler tool in Chapter 12
  • Complete source code for this recipe can be found in the \Chapter 1\recipe7\ folder
主站蜘蛛池模板: 浦江县| 利川市| 平邑县| 晋州市| 布拖县| 万安县| 庄河市| 曲靖市| 日照市| 张家口市| 惠水县| 大连市| 蓬莱市| 康定县| 容城县| 德兴市| 剑河县| 鸡泽县| 竹北市| 侯马市| 启东市| 西乡县| 游戏| 漳州市| 桓台县| 西华县| 道孚县| 辉县市| 长沙县| 清镇市| 北碚区| 三门县| 北票市| 江北区| 庆云县| 伽师县| 柯坪县| 商城县| 威宁| 宜州市| 启东市|