Writing Multiple Detail Elements in Faults

How do I create a fault with multiple child nodes for the detail element? All of the overloads of CreateFault take a single argument for detail, which lets me build a tree of nodes but not a forest.

The trick here is not to get hung up on trying to make the built-in convenience methods work. The object model for all of the message classes is just a wrapper around a way to interact with XML readers and writers. Notice that MessageFault is an abstract class. You can create your own subclasses to directly work against the underlying reader and writer.

Also notice that there are only four methods that you have to override to make a MessageFault: Code, Reason, HasDetail, and OnWriteDetailContents. Code and Reason are parameters that you would have had to pass to CreateFault anyway. If you care about how the contents of the detail element are structured, then you definitely have a detail element. That really just leaves OnWriteDetailContents to implement, which is exactly what you wanted to precisely control the contents of the detail element.

 class MyMessageFault : MessageFault
{
   FaultCode code;
   FaultReason reason;

   public MyMessageFault(FaultCode code, FaultReason reason)
   {
      this.code = code;
      this.reason = reason;
   }

   public override FaultCode Code
   {
      get { return this.code; }
   }

   public override bool HasDetail
   {
      get { return true; }
   }

   protected override void OnWriteDetailContents(XmlDictionaryWriter writer)
   {
      // You can write whatever XML you want here
   }

   public override FaultReason Reason
   {
      get { return this.reason; }
   }
}

On the reverse side, you'll have exactly the same problem with GetDetail because it too is limited to a single object. In this case though, you have the replacement directly accessible, GetReaderAtDetailContents, and are more likely to already have been using it.

Next time: Default ProtectionLevel for Standard Bindings