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

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
主站蜘蛛池模板: 奎屯市| 客服| 县级市| 遂溪县| 托克逊县| 客服| 台东市| 馆陶县| 鸡东县| 迁西县| 赤峰市| 曲周县| 华宁县| 恩施市| 鄂托克前旗| 出国| 邛崃市| 伊通| 宜州市| 胶州市| 伊金霍洛旗| 姚安县| 枞阳县| 宕昌县| 凤台县| 韶关市| 伊宁县| 延吉市| 修文县| 内丘县| 金华市| 华池县| 碌曲县| 南靖县| 稻城县| 镇宁| 昆山市| 龙山县| 泸水县| 天等县| 乐山市|