AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=727&pId=-1
CodeSnip: Handling SOAP Exceptions in Web Services
page
by Vishal Kumar Patil
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 53820/ 116

[Download Sample Code]

 

Overview

A Web service provides functionality independent of the programming languages and the operating system; hence, it’s necessary for the Web services to throw exceptions in a platform-independent manner. To accomplish this, we need to raise SOAP exceptions from the Web service that are compliant with the SOAP specification.

 

The following are the advantages of SOAP exceptions.

 

  • They handle exceptions in a consistent manner.
  • They follow the SOAP specification.
  • Explicitly raising SOAP exceptions communicates more information, such as detailed information of the exception, Web Service method name, and responsibility.

 

Now that we have had a look at the importance of raising SOAP exceptions, let us look at how to raise exceptions from Web services.

 

Raising Exceptions from Web Services

To accomplish this, we should use the SoapException class as it abstracts the complexities of the SOAP fault creation process. The SoapException class consists of the following properties that need to be populated before throwing the exception to the consumers.

 

  • Message—the contents of the exception.
  • Code—an enumeration that specifies the type of fault code (e.g. ClientFaultCode, ServerFaultCode, etc.).
  • Actor—the URL of the Web service method where the exception has occurred.
  • Detail—the detail element can be used to communicate more information about the exception to the callers.

 

For the purposes of this example, we’ll create a Web service named WSException, selecting a C# ASP.NET Web Service as the project template. Once the project is created, add a service called WSException and add a method named GetException and the following lines of code to that class.

 

Listing 1

public enum FaultCode

{

  Client = 0,

  Server = 1

}

 

[WebMethod]

public void GetException()

{

  try

  {

    int i = 1;

    int j = 0;

    int z;

 

    //generates the exception

    z = i / j;

  }

  catch (Exception ex)

  {

    throw RaiseException("GetException", "WSSoapException", ex.Message,

                      "1000", ex.Source, FaultCode.Server);

  }

}

 

//Creates the SoapException object with all the error details

public SoapException RaiseException(string uri, string webServiceNamespace,

                                string errorMessage,

                                string errorNumber,

                                string errorSource,

                                FaultCode code)

{

  XmlQualifiedName faultCodeLocation = null;

  //Identify the location of the FaultCode

  switch (code)

  {

    case FaultCode.Client:

      faultCodeLocation = SoapException.ClientFaultCode;

      break;

    case FaultCode.Server:

      faultCodeLocation = SoapException.ServerFaultCode;

      break;

  }

  XmlDocument xmlDoc = new XmlDocument();

  //Create the Detail node

  XmlNode rootNode = xmlDoc.CreateNode(XmlNodeType.Element,

                                SoapException.DetailElementName.Name,

                                SoapException.DetailElementName.Namespace);

  //Build specific details for the SoapException

  //Add first child of detail XML element.

  XmlNode errorNode = xmlDoc.CreateNode(XmlNodeType.Element, "Error",

                                        webServiceNamespace);

  //Create and set the value for the ErrorNumber node

  XmlNode errorNumberNode =

    xmlDoc.CreateNode(XmlNodeType.Element, "ErrorNumber",

                      webServiceNamespace);

  errorNumberNode.InnerText = errorNumber;

  //Create and set the value for the ErrorMessage node

  XmlNode errorMessageNode = xmlDoc.CreateNode(XmlNodeType.Element,

                                              "ErrorMessage",

                                              webServiceNamespace);

  errorMessageNode.InnerText = errorMessage;

  //Create and set the value for the ErrorSource node

  XmlNode errorSourceNode =

    xmlDoc.CreateNode(XmlNodeType.Element, "ErrorSource",

                      webServiceNamespace);

  errorSourceNode.InnerText = errorSource;

  //Append the Error child element nodes to the root detail node.

  errorNode.AppendChild(errorNumberNode);

  errorNode.AppendChild(errorMessageNode);

  errorNode.AppendChild(errorSourceNode);

  //Append the Detail node to the root node

  rootNode.AppendChild(errorNode);

  //Construct the exception

  SoapException soapEx = new SoapException(errorMessage,

                                           faultCodeLocation, uri,

                                           rootNode);

  //Raise the exception  back to the caller

  return soapEx;

}

 

 

In the above listing, as the name suggests, the GetException Web method throws the exception (as we are dividing 1 by 0 to generate the exception) when it is called from the client side. This exception is converted into the SoapException object by the RaiseException method which is called in the catch block of the GetException Web method.

 

In the above code, the RaiseException method is used to raise exceptions from the Web service in the form of a SoapException object. The RaiseException method first looks at the FaultCode enum parameter value to find out the source of the exception. If an exception has occurred due to problems in the server side (for example, the file is not found), it sets the value of FaultCode to SoapException.ServerFaultCode.

 

Similarly, if an exception has occurred due to a problem in the input parameter passed by the client to the Web method, then FaultCode is set to SoapException.ClientFaultCode. Once it is done, it creates an XmlDocument object to hold the contents of the detail element. It adds all the child elements under the detail element and then passes the detail node to the constructor of the SoapException object. Finally, it returns the SoapException object back to the caller by using the return statement. Detail element inside the SoapException object will look as follows.

 

Listing 2

<detail>

  <Error xmlns=" http://tempuri.org/WSException /">

    <ErrorNumber>1000</ErrorNumber>

    <ErrorMessage>Exception Message</ErrorMessage>

    <ErrorSource>Exception Source</ErrorSource>

  </Error>

</detail>

 

When the client application receives a SoapException from the Web service, it looks at the Detail property of the SoapException object to get more information about the generated exception.

 

Handling Exceptions at the Client Side

This section provides an example to handle the exceptions raised from the Web service on the client side. To demonstrate this, let us create a new GUI project named SoapException. Once the project is created, add a command button to the default form and name it RaiseException. Add a Web Reference to the WSException project (see Listing 1). Then modify the Click event of the command button to look like the following.

 

Listing 3

public void RaiseException_Click(object sender,

  System.EventArgs e)

{

  try

  {

    WSException WSEx = new WSException();

    WSEx.GetException();

  }

  catch (SoapException soapEx)

  {

    MessageBox.Show(soapEx.Code.ToString());

    //Load the Detail element of the SoapException object

    XmlDocument doc = new XmlDocument();

    doc.LoadXml(soapEx.Detail.OuterXml);

    XmlNamespaceManager nsManager = new

      XmlNamespaceManager(doc.NameTable);

    // Add the namespace to the NamespaceManager

    nsManager.AddNamespace("errorNS",

      "WSSoapException");

    XmlNode Node =

      doc.DocumentElement.SelectSingleNode("errorNS:Error",

                                           nsManager);

    string errorNumber =

      Node.SelectSingleNode("errorNS:ErrorNumber",

                                    nsManager).InnerText;

    string errorMessage =

    Node.SelectSingleNode("errorNS:ErrorMessage",

                                nsManager).InnerText;

    string errorSource =

    Node.SelectSingleNode("errorNS:ErrorSource",

                                nsManager).InnerText;

    MessageBox.Show("Error Number is " + errorNumber);

    MessageBox.Show("Error Message is " + errorMessage);

    MessageBox.Show("Error Source is " + errorSource);

 

  }

  catch (Exception ex)

  {

    MessageBox.Show(ex.Message);

  }

}

 

Conclusion

In this article, we have demonstrated how to raise SOAP exceptions back to the client applications by using the SoapException object. We have also seen how the SoapException object allows us to communicate the exceptions using the SOAP fault code defined in the SOAP specification. Although the application we created was simple in functionality, it should provide a solid foundation for understanding how to raise and handle exceptions from a Web service.



©Copyright 1998-2014 ASPAlliance.com  |  Page Processed at 7/29/2014 4:52:40 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search