Serializing Faults using XmlSerializer
Update (25/08/2008): .net Framework 3.5 SP1 has added the support for serializing faults using XML Serializer.
[
------------------------------------------------------------------------------------------------------------------------------------------
Today someone asked me how to serialize the TDetail part of FaultException<TDetail> using XmlSerializer. The scenario was to interoperate with an existing schema using some of the XSD features (attributes etc.), which are currently not supported by DataContractSerializer. The solution is to Subclass the MessageFault class and use XmlSerializer to serialize the TDetail.
public class XmlSerializerMessageFault : MessageFault
{
FaultCode code;
FaultReason reason;
object details;
public XmlSerializerMessageFault(FaultCode code, FaultReason reason, object details)
{
this.details = details;
this.code = code;
this.reason = reason;
}
public override FaultCode Code
{
get { return code; }
}
public override bool HasDetail
{
get { return (details != null); }
}
protected override void OnWriteDetailContents(System.Xml.XmlDictionaryWriter writer)
{
var ser = new XmlSerializer(details.GetType());
ser.Serialize(writer, details);
writer.Flush();
}
public override FaultReason Reason
{
get { return reason; }
}
}
Fault was created from a global error handler (IErrorHandler).
public class ErrorHandlerEx : IErrorHandler
{
public bool HandleError(Exception error)
{
return true;
}
public void ProvideFault(
Exception error, MessageVersion version, ref Message fault)
{
if (error is FaultException)
{
// extract our FaultContract object from the exception object.
var detail = error.GetType().GetProperty("Detail").GetGetMethod().Invoke(error, null);
// create a fault message containing our FaultContract object
var msgFault = new XmlSerializerMessageFault(FaultCode.CreateSenderFaultCode("systemDown", "http://zamd.net"), new FaultReason("System is down"), detail);
fault = Message.CreateMessage(version, msgFault, "http://zamd.net/action");
}
}
}
Xml output
<Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">
<Code>
<Value>Sender</Value>
<Subcode>
<Value xmlns:a="http://zamd.net">a:systemDown</Value>
</Subcode>
</Code>
<Reason>
<Text xml:lang="en-GB">System is down</Text>
</Reason>
<Detail>
<GreaterThan3Fault ErrorCode="90192" Location="ISB" xmlns="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<FaultMessage>Count cannot be greate than 3. Please try again later.</FaultMessage>
</GreaterThan3Fault>
</Detail>
</Fault>