Handling SOAP faults with HttpWebResponse object

When you call web services, in normal cases you would use the web service proxy objects that gets generated when you add a web reference and not send in an HTTP POST to the web service. I had an interest case recently where we had to build a test client that accepted invalid SOAP requests with malformed XML as well as well-formed SOAP requests.

If the web service returns a normal response, we can handle the response and just parse the returned XML. The code is what you would expect

 
try
{

WebResponse webResponse = webRequest.GetResponse();

if (webResponse != null)
{
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
response = sr.ReadToEnd().Trim();
}
}
catch (Exception ex)
{
// Handle the request
}


However, if the web service throws a SOAP fault when we try to get the response, the stack trace of the exception will not return the SOAP fault that you would expect. Instead we just a fairly generic error message and an HTTP 500 Internal Server error.



What's going on? If we use a HTTP sniffer to see the actual raw response we get some clues.
 
HTTP/1.1 500 Server Error
Server: Sun-ONE-Web-Server/6.1
Date: Wed, 15 Apr 2009 00:42:33 GMT
Content-length: 978
Content-type: text/xml; charset=utf-8
X-Powered-By: Servlet/2.4 JSP/2.0
X-Charles-Received-Continue: HTTP/1.1 100 Continue

 
soapenv:ServerSchema validation failed for request.5
Schema validation failed for request.
string value 'MVP_CUSTOMER' is not a valid enumeration value for CustomerType in namespace
http://acme.com/ws/customerorder/v1
MVP_CUSTOMER





It's apparent that the web server interprets a SOAP fault as an HTTP 500 error so it has nothing to do with HttpWebResponse class doing something invalid. When we sniffed the HTTP traffic, we could see the detailed SOAP fault information so why can't see it when we catch an exception?

We need to catch a WebException and then cast the WebException.Response into an HttpWebResponse object. Once we have a valid HttpWebResponse object, we can read the response stream and get the SOAP fault information out. We can then extract the information and turn it into a useful error messages for the logfile or the users.

 
try
{

WebResponse webResponse = webRequest.GetResponse();

if (webResponse != null)
{
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
response = sr.ReadToEnd().Trim();
}
}

catch (WebException wex)
{
// We issued an HttpWebRequest, so the response will be an
// HttpWebResponse.
HttpWebResponse httpResponse = wex.Response as HttpWebResponse;

// Grab the response stream.
using (Stream responseStream = httpResponse.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
{
// Grab the body of the response as a string for parsing.
string failureReason = reader.ReadToEnd();

// If it failed with a SOAP fault, parse the response body into a usable exception.
ThrowIfSoapFault(failureReason);

// If it was not a SOAP fault, rethrow the original exception.
throw;
}
}

}



Most of the code shown in this example can be found at MSDN.

SiteFinity - using SWF files

I've finally had a chance to continue with my POC to try to integrate my SWF file into SiteFinity. It went pretty smoothly but there was quite a bit of manual work. I haven't had a chance to look at version 3.6 of SiteFinity yet, I hope later versions would have a control that would handle the browser initialization of the SWF file and helping take care of the reference to the SWF file.

I've heard a lot of buzz about swfobject which is a JavaScript based framework that instantiates Flash based content regardless of browser, I decided to try it out to see how I would like it. After working for a Fortune 500 company, you learn to worry about what license any open source projects uses, swfobject uses the MIT license which is a plus. It has a nice wizard that will help you set up the appropriate attributes which really helps when you're unfamiliar how to use it in the beginning.

In SiteFinity, the only way I have found from my initial research is to add it to the Master Page. Hopefully there's a better way than to be forced to have the user get the JavaScript downloaded to the browser or have to add a custom user control if you just have a handful of pages where you use SWF files. I decided to just link to the Google Code repository but you probably want to include it in your website in production scenarios.



I just uploaded my SWF file to the Files section in SiteFinity and then added it via an OBJECT tag in a Generic Control. I have not been able the get the file reference of the SWF file to be resolved inside the OBJECT so I can use a relative reference like for the server side controls in SiteFinity. Instead, I've had to put the full URL to the file which is a pain point if you have separate QA and Production environments. It appears that others in the SiteFinity forums also have struggled with this but hopefully I'm just overlooking something.



The actual page shows the SWF file as we would expect.



It is a relatively easy process to add a SWF to SiteFinity but hopefully there will be an easier way to add it in the future and control it better.