Reputation: 1066
This is what I ideally want to do
public void AfterReceiveReply(ref Message reply, object correlationState)
{
if (reply.IsFault)
{
FaultException exp = reply.GetBody<FaultException>();
if (exp.Code.Name == "MyFaultCode")
{
//Do something here
}
}
}
but I get this exception
Error in line 1 position 82. Expecting element 'FaultException' from namespace 'http://schemas.datacontract.org/2004/07/System.ServiceModel'.. Encountered 'Element' with name 'Fault', namespace 'http://schemas.xmlsoap.org/soap/envelope/'.
when I try to do
FaultException exp = reply.GetBody<FaultException>();
From the server side this is how I throw the exception.
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext
instanceContext)
{
throw new FaultException("MyFaultCode", new FaultCode("MyFaultCode"));
}
Can someone please tell me how to deserialize the Fault Exception from the message so that I can access the FaultCode?
Upvotes: 3
Views: 4003
Reputation: 1110
you can extract fault information directly from System.ServiceModel.Channels.Message class (here in message variable):
var fault = MessageFault.CreateFault(message, int.MaxValue);
Then from this fault you can read fault code or message:
var error = fault.Reason.GetMatchingTranslation().Text;
To sum up, you can create a simple validation method:
private static void ValidateMessage(Message message)
{
if (!message.IsFault) return;
var fault = MessageFault.CreateFault(message, int.MaxValue);
var error = fault.Reason.GetMatchingTranslation().Text;
//do something :)
}
Upvotes: 3
Reputation: 1066
This is how I actually did it... Stack Overflow solution
public void AfterReceiveReply(ref Message reply, object correlationState)
{
if (reply.IsFault)
{
MessageBuffer buffer = reply.CreateBufferedCopy(Int32.MaxValue);
XmlDictionaryReader xdr = buffer.CreateMessage().GetReaderAtBodyContents();
XNode xn = XDocument.ReadFrom(xdr);
string s = xn.ToString();
XDocument xd = XDocument.Parse(s);
XNamespace nsSoap = "http://schemas.xmlsoap.org/soap/envelope/";
XNamespace ns = "";
XElement xErrorCode = xd.Element(nsSoap + "Fault").Element("faultcode");
if (xErrorCode.Value.Contains("MyFaultCode"))
{
// Redirect to login page
}
reply = buffer.CreateMessage();
buffer.Close();
}
}
Upvotes: 2
Reputation: 1
I don't know if .NET has that type built in, but here's how you can generate it yourself:
Run the command:
svcutil /dconly /importxmltypes envelope.xml
But is this really what you "ideally want to do"?
If you're throwing that FaultException is the server, shouldn't you be able to catch it directly in the client?
Or even better, use the FaultContract attribute on your operation contracts to handle custom fault exceptions.
Upvotes: 0