I am trying to use the recommended code from this page http://blogs.msdn.com/b/nathana/archive/2011/03/31/deciphering-a-soap-fault-with-a-400-status-code.aspx as follows:
static FaultException ParseProtocolExecption(ProtocolException ex)
{
try
{
System.IO.Stream stream = (ex.InnerException as WebException).Response.GetResponseStream();
System.Xml.XmlReader xmr = System.Xml.XmlReader.Create(stream);
Message message = Message.CreateMessage(xmr, (int)stream.Length, MessageVersion.Soap12);
MessageFault mf = MessageFault.CreateFault(message, (int)stream.Length);
FaultException fe = new FaultException(mf);
message.Close();
return fe;
}
catch (Exception)
{
return new FaultException(ex.Message);
}
}
I am using VS 2012 with .NET 4.5 using WCF. When the app gets a 400 Bad Request and it passes the ProtocolException to ParseProtocolException, it throws an exception on this line:
Message message = Message.CreateMessage(xmr, (int)stream.Length, MessageVersion.Soap12);
with the System.ServiceModel.CommunicationException: "The size necessary to buffer the XML content exceeded the buffer quota."
The stream.Length = 2,704 bytes, which is not very big. I tried the solution suggested on this site http://blogs.msdn.com/b/drnick/archive/2007/08/07/increasing-the-maximum-fault-size.aspx. However, even with the MaxFaultSize = 1 Mb, it gets the same errror.
Instead of this line:
System.Xml.XmlReader xmr = System.Xml.XmlReader.Create(stream);
I've tried this:
xmr = XmlDictionaryReader.CreateTextReader(stream, XmlDictionaryReaderQuotas.Max);
which sets all the quotas to their maximum value (Int32.MaxValue); but, I still get the same error on the CreateMessage call.
A sample response stream from the System.Net.WebException is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa5="http://www.w3.org/2005/08/addressing" xmlns:c14n="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:xmime5="http://www.w3.org/2005/05/xmlmime" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:tds2="http://www.onvif.org/ver10/schema" xmlns:tds3="http://docs.oasis-open.org/wsn/b-2" xmlns:tds4="http://docs.oasis-open.org/wsrf/bf-2" xmlns:tds5="http://docs.oasis-open.org/wsn/t-1" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:tan="http://www.onvif.org/ver20/analytics/wsdl" xmlns:tds6="http://www.canon.com/ns/networkcamera/onvif/va/schema" xmlns:tmd="http://www.onvif.org/ver10/deviceIO/wsdl" xmlns:tev="http://www.onvif.org/ver10/events/wsdl" xmlns:tds9="http://docs.oasis-open.org/wsrf/r-2" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:ter="http://www.onvif.org/ver10/error">
<SOAP-ENV:Header></SOAP-ENV:Header>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<SOAP-ENV:Code>
<SOAP-ENV:Value>SOAP-ENV:Sender</SOAP-ENV:Value>
<SOAP-ENV:Subcode>
<SOAP-ENV:Value>ter:NotAuthorized</SOAP-ENV:Value>
</SOAP-ENV:Subcode>
</SOAP-ENV:Code>
<SOAP-ENV:Reason>
<SOAP-ENV:Text xml:lang="en">Sender Not Authorized</SOAP-ENV:Text>
</SOAP-ENV:Reason>
<SOAP-ENV:Node>http://www.w3.org/2003/05/soap-envelope/node/ultimateReceiver</SOAP-ENV:Node>
<SOAP-ENV:Role>http://www.w3.org/2003/05/soap-envelope/role/ultimateReceiver</SOAP-ENV:Role>
<SOAP-ENV:Detail>The action requested requires authorization and the sender is not authorized</SOAP-ENV:Detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Using an async web crawler that I wrote in F# Interactive, I found that some of the namespace url's were not resolvable. I corrected the erroneous ones and then ran the crawler again to sum the lengths of the namespace pages. The total is 715,965 bytes, which is much less than the Int32.MaxValue of all the quotas in XmlDictionaryReaderQuotas. Perhaps the XmlDictionaryReader has a bug, or the error it returns is not the real problem?
I finally got the Message creation to work by removing the namespace definitions that were not actually used in the SOAP-ENV:Body (i.e., keeping only the xmlns:ter used in the Subcode element). But, of course, this doesn't really solve the problem, because the service is generating the SOAP fault; and I cannot change the service implementation (it's a 3rd party device - an Onvif camera).
Morevover, I can't make the quotas any greater; so, how else to handle this exception?