Sometimes during development I want to have a light-weight approach to logging request and response messages without setting up WCF tracing. Regardless of how I am logging (Trace, EntLib, whatever), I need to get a printable version of the data message.
I always recommend treating DataContract classes strictly as data transfer objects (DTO), that is they exist purely for describing the shape of the message on the wire. That means I don’t add any fancy constructors or business logic of any kind to the DTOs. This maintains a separation of concerns. However, all CLR types do have a ToString method, so I an fine with putting it to better use than telling me the name of the type.
In the sample code, CreateSecretRequest overrides ToString using a static helper method, Helper.ToXmlString. That helper method wraps an XmlSerializer and a StringWriter together to serialize the DTO to a string of XML that I can log. All DataContract classes can use the same ToXmlString method to implement their override of ToString in a simple one-liner.
using System.IO; using System.Xml.Serialization; public static class Helper { public static string ToXmlString( object value, string defaultNamespace ) { var writer = new StringWriter(); (new XmlSerializer( value.GetType(), defaultNamespace )).Serialize( writer, value ); return writer.ToString(); } } // a sample data transfer object using System.Runtime.Serialization; [DataContract( Namespace = XmlNamespaces.Secret.CreateSecretRequest )] public class CreateSecretRequest { [DataMember] public string Name { get; set; } [DataMember] public string Description { get; set; } public override string ToString() { return Helper.ToXmlString( this, XmlNamespaces.Secret.CreateSecretRequest ); } }
Be careful! This is not the same XML that the service sent or received on the wire. Use WCF Tracing to see what is really happening with your services. This is nearly a 100% genuine approximation of the message, suitable for some quick-and-dirty logging or debugging diagnostics.