I fear I already know the answer, but does Silverlight support SOAP faults? When I throw a FaultException on the server, the client just creates an UnexpectedHttpResponseCode and all the fault information is lost. Is this just a really bad Beta 1 bug, or
a fundamental design flaw, or some kind of WCF-misconfiguration?
Without fault support, SL WCF is pretty much useless for anything above "cutesy AJAX replacement" (OK, well, not that bad, but pretty bad for LOB type apps). No fault support at all means no way for services to return error information. (No, modifying each
return type to include an optional error information is NOT a solution.)
Can anyone fill me in on the idea here? Using Fiddler I can see the HTTP 500 response with my SOAP envelope and fault. I'm guessing WCF-generated faults don't come back in an HTTP 200 OK and for some reason Silverlight can't support them. Is there a way
to configure WCF to return an HTTP 200 with the fault information?
Rewrites all 500s to 200s. It probably isn't too hard to filter it down to only doing this for WCF service responses if the client is a webbrowser/silverlight. Unfortunately, Silverlight still fails:
Error: System.Runtime.Serialization.SerializationException: OperationFormatter encountered an invalid Message body. Expected to find node type 'Element' with name 'DeletePartitionResponse' and namespace 'http://schemas.packetrino.com/management/v2/00'. Found
node type 'Element' with name 's:Fault' and namespace 'http://schemas.xmlsoap.org/soap/envelope/'
at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)
at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)
at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeReply(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.ProxyOperationRuntime.AfterReply(ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
...
I tried adding a typed fault to my service, just on the off-chance that this somehow would help. Turns out Silverlight 2 Beta 1 doesn't even have the bits necesary to reference such a service.
I get the FaultContractAttribute applied to the generated interface in SL, but apparently that type doesn't exist. So I'm guessing that yes, fault support is nowhere to be found (despite the fact that FaultException exists).
We're really hoping to see FaultException<T> / FaultContract support too - having to add an error code to every return type is not a good answer. Hope to see this fixed in Beta2 - ??
Is there any trick to getting the System.Runtime.Serialization.SerializationException exception in the Silverlight proxy?
I'm modifying the response code from 500 to 200 on the reponses being sent to Silverlight but instead of the SerializationException I'm getting a NullReferenceException presumamby when Silverlight tries and fails to deserialise the return object from the
response.
If I send back valid XML from global.asax I don't get an exception until I try and use the result object which is where the NullReference comes in.
If I send back invalid XML from global.asax I get a stack trace of:
{System.Xml.XmlException: [Xml_TagMismatch]
Arguments:faultstring,1,soap:Fault
Debugging resource strings are unavailable. Often the key and arguments provide sufficient information to diagnose the problem. See
http://go.microsoft.com/fwlink/?linkid=106663&Version=2.0.30226.2&File=System.Xml.dll&Key=Xml_TagMismatch [Xml_ErrorPosition]
Arguments:1,187
Debugging resource strings are unavailable. Often the key and arguments provide sufficient information to diagnose the problem. See
http://go.microsoft.com/fwlink/?linkid=106663&Version=2.0.30226.2&File=System.Xml.dll&Key=Xml_ErrorPosition
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.Throw(String res, String[] args)
at System.Xml.XmlTextReaderImpl.ThrowTagMismatch(NodeData startTag)
at System.Xml.XmlTextReaderImpl.ParseEndElement()
at System.Xml.XmlTextReaderImpl.ParseElementContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XmlDictionaryReader.XmlWrappedReader.Read()
at System.Xml.XmlReader.SkipSubtree()
at System.Xml.XmlReader.Skip()
at System.ServiceModel.Dispatcher.OperationFormatter.TraceAndSkipElement(XmlReader xmlReader)
at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameters(XmlDictionaryReader reader, PartInfo[] parts, Object[] parameters, Boolean isRequest)
at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)
at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)
at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeReply(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.ProxyOperationRuntime.AfterReply(ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
at
I'm playing around with sending back different payloads from global.asax to try and somehow get an exception thrown with the payload in the e.Error.Message but so far haven't been able to. An example of a payload I've tried sending is:
Here is the exact code I have in a production system and it works fine in conjunction with the rest of the code:
protected void Application_EndRequest(object sender, EventArgs e)
{
// In all fairness, I was drinking eiswein at the time
if (Context.Items.Contains("HackFault")) {
Context.Response.ContentType = "text/xml";
Context.Response.StatusCode = 200;
Context.Response.ClearContent();
var hackEx = Context.Items["HackFault"] as Exception;
var hackFaultXml = string.Format(
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><{0} xmlns=\"{1}\" /></s:Body></s:Envelope>",
hackEx.GetType().ToString(), Context.Server.HtmlEncode(hackEx.Message));
Context.Response.Output.Write(hackFaultXml);
}
}
MichaelGG
Member
86 Points
25 Posts
SL WCF can't handle faults?
Mar 26, 2008 08:03 AM | LINK
I fear I already know the answer, but does Silverlight support SOAP faults? When I throw a FaultException on the server, the client just creates an UnexpectedHttpResponseCode and all the fault information is lost. Is this just a really bad Beta 1 bug, or a fundamental design flaw, or some kind of WCF-misconfiguration?
Without fault support, SL WCF is pretty much useless for anything above "cutesy AJAX replacement" (OK, well, not that bad, but pretty bad for LOB type apps). No fault support at all means no way for services to return error information. (No, modifying each return type to include an optional error information is NOT a solution.)
Can anyone fill me in on the idea here? Using Fiddler I can see the HTTP 500 response with my SOAP envelope and fault. I'm guessing WCF-generated faults don't come back in an HTTP 200 OK and for some reason Silverlight can't support them. Is there a way to configure WCF to return an HTTP 200 with the fault information?
Thanks,
-Michael
MichaelGG
Member
86 Points
25 Posts
Re: SL WCF can't handle faults?
Mar 26, 2008 08:43 AM | LINK
OK, I found a brute-force way to quickly fix the HTTP 500 problem:
http://blogs.sparknettech.com/blog/2007/10/31/flex-webservice-error-handeling/
Rewrites all 500s to 200s. It probably isn't too hard to filter it down to only doing this for WCF service responses if the client is a webbrowser/silverlight. Unfortunately, Silverlight still fails:
Error: System.Runtime.Serialization.SerializationException: OperationFormatter encountered an invalid Message body. Expected to find node type 'Element' with name 'DeletePartitionResponse' and namespace 'http://schemas.packetrino.com/management/v2/00'. Found node type 'Element' with name 's:Fault' and namespace 'http://schemas.xmlsoap.org/soap/envelope/'
at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)
at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)
at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeReply(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.ProxyOperationRuntime.AfterReply(ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
...
Any ideas from here?
MichaelGG
Member
86 Points
25 Posts
Re: SL WCF can't handle faults?
Mar 26, 2008 08:59 AM | LINK
I tried adding a typed fault to my service, just on the off-chance that this somehow would help. Turns out Silverlight 2 Beta 1 doesn't even have the bits necesary to reference such a service.
I get the FaultContractAttribute applied to the generated interface in SL, but apparently that type doesn't exist. So I'm guessing that yes, fault support is nowhere to be found (despite the fact that FaultException exists).
I guess I just have to wait 'till Beta 2?
-Michael
Kim Johnson
Member
8 Points
8 Posts
Re: SL WCF can't handle faults?
Mar 26, 2008 04:52 PM | LINK
We're really hoping to see FaultException<T> / FaultContract support too - having to add an error code to every return type is not a good answer. Hope to see this fixed in Beta2 - ??
MichaelGG
Member
86 Points
25 Posts
Re: SL WCF can't handle faults?
Mar 27, 2008 07:21 AM | LINK
Well I got a cheap hackaround to at least allow some faulting with Silverlight: http://www.atrevido.net/blog/2008/03/27/Hacking+SOAP+Faults+Into+Silverlight+2+Beta+1.aspx
It's cheap, it's hacky, but it gives me enough to deal with until Beta 2.
aaronc
Member
78 Points
41 Posts
Re: Re: SL WCF can't handle faults?
Apr 09, 2008 03:26 AM | LINK
Is there any trick to getting the System.Runtime.Serialization.SerializationException exception in the Silverlight proxy?
I'm modifying the response code from 500 to 200 on the reponses being sent to Silverlight but instead of the SerializationException I'm getting a NullReferenceException presumamby when Silverlight tries and fails to deserialise the return object from the response.
Regards,
Aaron
MichaelGG
Member
86 Points
25 Posts
Re: Re: SL WCF can't handle faults?
Apr 09, 2008 03:44 AM | LINK
I have sample code on my site. But no, I didn't have to do anything that I recall. Can you post a full stacktrace?
aaronc
Member
78 Points
41 Posts
Re: Re: Re: SL WCF can't handle faults?
Apr 09, 2008 04:12 AM | LINK
If I send back valid XML from global.asax I don't get an exception until I try and use the result object which is where the NullReference comes in.
If I send back invalid XML from global.asax I get a stack trace of:
{System.Xml.XmlException: [Xml_TagMismatch]
Arguments:faultstring,1,soap:Fault
Debugging resource strings are unavailable. Often the key and arguments provide sufficient information to diagnose the problem. See http://go.microsoft.com/fwlink/?linkid=106663&Version=2.0.30226.2&File=System.Xml.dll&Key=Xml_TagMismatch [Xml_ErrorPosition]
Arguments:1,187
Debugging resource strings are unavailable. Often the key and arguments provide sufficient information to diagnose the problem. See http://go.microsoft.com/fwlink/?linkid=106663&Version=2.0.30226.2&File=System.Xml.dll&Key=Xml_ErrorPosition
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.Throw(String res, String[] args)
at System.Xml.XmlTextReaderImpl.ThrowTagMismatch(NodeData startTag)
at System.Xml.XmlTextReaderImpl.ParseEndElement()
at System.Xml.XmlTextReaderImpl.ParseElementContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XmlDictionaryReader.XmlWrappedReader.Read()
at System.Xml.XmlReader.SkipSubtree()
at System.Xml.XmlReader.Skip()
at System.ServiceModel.Dispatcher.OperationFormatter.TraceAndSkipElement(XmlReader xmlReader)
at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameters(XmlDictionaryReader reader, PartInfo[] parts, Object[] parameters, Boolean isRequest)
at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)
at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)
at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeReply(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.ProxyOperationRuntime.AfterReply(ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
at
I'm playing around with sending back different payloads from global.asax to try and somehow get an exception thrown with the payload in the e.Error.Message but so far haven't been able to. An example of a payload I've tried sending is:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <soap:Fault><faultcode>soap:Server</faultcode><faultstring>Test fault message</faultstring><detail /></soap:Fault> </soap:Body></soap:Envelope>
Regards,
Aaron
aaronc
Member
78 Points
41 Posts
Re: Re: Re: Re: SL WCF can't handle faults?
Apr 09, 2008 04:52 AM | LINK
Does using the following script for global.asax generate an exception in Silverlight?
<script runat="server" language="c#">
protected void Application_EndRequest(object sender, EventArgs e)
{
if (Context.Response.StatusCode == 500)
{
Context.Response.ContentType = "text/xml";
Context.Response.StatusCode = 200;
Context.Response.ClearContent();
string soapFault =
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
" <soap:Body>" +
" <SomeNS.SomeClass xmlns=\"test 1 2 3 4\" />" +
" </soap:Body>" +
"</soap:Envelope>";
Context.Response.Output.Write(soapFault);
}
}
</script>
For me it gets accepted and puts a System.NullReferenceException into e.Error.
Regards,
Aaron
MichaelGG
Member
86 Points
25 Posts
Re: Re: Re: Re: SL WCF can't handle faults?
Apr 09, 2008 05:33 AM | LINK
Here is the exact code I have in a production system and it works fine in conjunction with the rest of the code:
protected void Application_EndRequest(object sender, EventArgs e)
{
// In all fairness, I was drinking eiswein at the time
if (Context.Items.Contains("HackFault")) {
Context.Response.ContentType = "text/xml";
Context.Response.StatusCode = 200;
Context.Response.ClearContent();
var hackEx = Context.Items["HackFault"] as Exception;
var hackFaultXml = string.Format(
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><{0} xmlns=\"{1}\" /></s:Body></s:Envelope>",
hackEx.GetType().ToString(), Context.Server.HtmlEncode(hackEx.Message));
Context.Response.Output.Write(hackFaultXml);
}
}