SOAP Exceptions and Errors


The SOAP body can also contain error information. You can send this error information as XML elements. Web method exceptions returned to a .NET application are automatically packaged as SOAP faults. .NET proxy classes package SOAP faults as exceptions, which makes them easier to handle. A SOAP fault can be parceled up either as a System.Web.Services.Protocols.SoapException object or a System.Web.Services.Protocols.SoapHeaderException object. The SoapException and SoapHeaderException objects function as a wrapper to the fault message. However, before we look at how to deal with SOAP faults in .NET, we’ll look at the structure of the <fault> element that SOAP provides.

The <fault> Element

In the SOAP 1.1 standard, the <fault> element is specified as having four parts: <faultcode>, <faultstring>, <faultactor>, and <detail>. A typical SOAP fault element is enclosed inside the SOAP body and might look like this:

<soap:Body>     <soap:Fault>         <faultcode>rs:application:database</faultcode>         <faultstring>Could not add record to              database</faultstring>         <faultactor></faultactor>         <detail></detail>     </soap:Fault> </soap:Body>

The SOAP body can contain only one fault, even if there are several. To see an example of a SOAP fault element generated by an application, we can go back to our record store Web service and generate one. All we need to do is amend the code in our ASP.NET client SOAPsender.aspx to send something via the SOAP request that isn’t strictly legal. If we remove the closing <GetArtist> or <GetTitle> element as follows, a SOAP fault is duly returned, informing us of our omission (as shown in Figure 2-6).

  string lbs = listBox1.SelectedItem.Text; string actionName = "/Get" + lbs; string soapBody = "<?xml version = \"1.0\" encoding = \"utf-8\" "     + "?><soap:Envelope "     + "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" "     + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "       + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"     + "<soap:Body><Get" + lbs      + "  xmlns=\"http://tempuri.org/\"><"+lbs+">"      + txtUserInput.Text + "</" + lbs + "></soap:Body>"     + "</soap:Envelope>"; RecordFinder5.ASPNETclient wsp = new RecordFinder5.ASPNETclient();  

click to expand
Figure 2-6: SOAP fault indicating that the closing <GetArtist> element was not found

Four separate elements are within <soap:Fault>, but in this example only two of them are returned containing any information. Of the others, one is empty and one is absent. Let’s take a look at what each of the subelements does.

<faultcode>

The <faultcode> element can contain any fully qualified application name to indicate where an error might have occurred. In our example, it just specifies soap:Client. The two possible entries by default are soap:Client and soap:Server, which simply indicate who’s responsible for the error. In our example, because the message created and sent by the client is ill formed, the faultcode returned is soap:Client. Had we shut down the SQL server instead, the service would have returned a soap:Server fault code.

The SOAP 1.2 standard mentions five possible fault codes:

  • DataEncodingUnknown The type of encoding used within some or all of the SOAP elements isn’t recognized by the endpoint.

  • MustUnderstand An element marked with a mustUnderstand attribute wasn’t processed.

  • Receiver An endpoint has generated an error that has nothing to do with the content of the SOAP message. This is the SOAP 1.2 name for the SOAP 1.1 fault code Server.

  • Sender An endpoint has generated an error caused by information or the format not conforming to the endpoints specifications. This is the SOAP 1.2 name for the SOAP 1.1 fault code Client.

  • VersionMismatch The Web service expected a SOAP 1.2 message but received a message qualified with the SOAP 1.1 namespace.

Note that in SOAP 1.2 the fault code here is represented by an element named Code, as opposed to <faultcode> in SOAP 1.1.

<faultstring>

The <faultstring> element provides a text message to the user describing why the fault happened. This message can be presented via a text box, dialog box, or something similar. In our example, it provides extensive information about what caused the fault (the missing closing tag) and where the opening tag is located. SOAP 1.2 calls this element <Reason>.

<detail>

The optional <detail> element describes something that happened when the SOAP body was being processed; it can be used to bundle up extended error information. In SOAP 1.2, the element name is <Detail>.

<faultactor>

The <faultactor> element is also optional and is used to specify the endpoint that caused the fault. By default, this is ultimateReceiver. SOAP 1.2 refines this approach and allows you to return the URI of the Web service sending the fault (the actor) in a Node element and the role the actor is currently playing in the new Role element.

The SoapException Object

The elements we just described map almost directly to the properties provided by the .NET SoapException object. This object can take an array of XML elements that it can forward back to the client. It has the following properties:

  • Code An object containing details about the source of the exception

  • Detail Application-specific details that relate to the SOAP body

  • Actor The endpoint that threw the exception

The SoapException object also inherits the following properties from the Exception class:

  • HelpLink The link to the help file associated with the exception

  • InnerException The inner exception containing more details about the fault that generated the exception

  • Message The message describing the exception

  • Source The application that caused the exception

  • StrackTrace A string of the frames on the call stack when the exception was thrown

  • TargetSite The method that threw the exception

You can use the SoapException object to throw a SOAP exception within a Web method and then query the properties. Throwing a SOAP exception is as simple as the following code, which manually generates an exception:

throw new SoapException("This will cause an error",      SoapException.ServerFaultCode);

You can take the details created and read them into a XMLDocument object, as described shortly. First we’ll consider the code object.

The Code Object

The Code object can be set to one of a number of constants that map partially to the errors generated in the <faultcode> element. The fault code constants are as follows in .NET:

  • VersionMismatchFaultCode An invalid namespace was sent.

  • MustUnderstandFaultCode An element marked “must process” wasn’t processed.

  • ClientFaultCode The content of the message caused a processing error.

  • ServerFaultCode A processing error occurred that wasn’t caused by the content of the message.

These constants help add to detail to the error generated. There is also a name property of the code object that supplies more details about the constant that created the error.

Example of Passing a Fault

You can see in the following example how the SoapException class works and what information is passed in SOAP messages. If we augment our previous example by adding a new Web method to cause an error, we can throw an exception that causes a SOAP fault as follows:

[WebMethod] public void SOAPFault() {     XmlDocument faultdoc = new XmlDocument();     XmlNode[] faultnodes = new XmlNode[1];     faultnodes[0] = faultdoc.CreateNode(XmlNodeType.Element,          "SOAPFaultException","http://testserver/");     faultnodes[0].InnerText = "This is a SOAP error";     throw new SoapException("This will cause an error",          SoapException.ServerFaultCode,          Context.Request.Url.AbsoluteUri, faultnodes[0], null); }

We can handle the SOAP fault by adding the following code to our client:

  RecordFinder5.SoapHeader1 header1 = new RecordFinder5.SoapHeader1(); header1.loginname = UserLogin.Text; RecordFinder5.Service1 chk = new RecordFinder5.Service1(); try {     chk.SOAPFault(); } catch(System.Web.Services.Protocols.SoapException SoapExcep) {     Response.Write("Error Message: " + SoapExcep.Message);     Response.Write("<br>Role: " + SoapExcep.Actor);     Response.Write("<br> Fault Code: " + SoapExcep.Code.Name); }  

This error is parceled up in the SoapException object, and we return information to the screen by querying the SoapException object’s Message and Actor properties, and the Name property of the Code object, as shown in Figure 2-7.

click to expand
Figure 2-7: Client application displaying details of a SoapException object to the user

The details are displayed to the user in a more user-friendly format; it is up to you whether you continue with the execution or end it there.




Programming Microsoft. NET XML Web Services
Programming MicrosoftВ® .NET XML Web Services (Pro-Developer)
ISBN: 0735619123
EAN: 2147483647
Year: 2005
Pages: 172

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net