1/4/2009
Include XML Declaration in WCF RESTful Service Response
When using WCF to write RESTful web services, the default XML response stream doesn’t contain the XML Declaration or XML DOCTYPE. the default XML serialization mechanism used by WCF’s data contract serializer does support emitting XML declaration, but it isn’t turned out by default. You could try using XmlSerializer instead which does support emitting XML declaration, but if you need stick to data contract serializer, you could try hooking into the WCF serialization process by writing a custom message formatter, the following code contains the full implementation of this approach:
public class XmlDeclarationMessage : Message
{
private Message message;
public XmlDeclarationMessage(Message message)
{
this.message = message;
}
public override MessageHeaders Headers
{
get { return message.Headers; }
}
protected override void OnWriteBodyContents(System.Xml.XmlDictionaryWriter writer)
{
// WCF XML serliazation doesn't support emitting XML DOCTYPE, you need to roll up your own here.
writer.WriteStartDocument();
message.WriteBodyContents(writer);
}
public override MessageProperties Properties
{
get { return message.Properties; }
}
public override MessageVersion Version
{
get { return message.Version; }
}
}
public class XmlDeclarationMessageFormatter : IDispatchMessageFormatter
{
private IDispatchMessageFormatter formatter;
public XmlDeclarationMessageFormatter(IDispatchMessageFormatter formatter)
{
this.formatter = formatter;
}
public void DeserializeRequest(Message message, object[] parameters)
{
formatter.DeserializeRequest(message, parameters);
}
public Message SerializeReply(MessageVersion messageVersion, Object[] parameters, Object result)
{
var message = formatter.SerializeReply(messageVersion, parameters, result);
return new XmlDeclarationMessage(message);
}
}
public class IncludeXmlDeclarationAttribute : Attribute, IOperationBehavior
{
public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
{
}
public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
dispatchOperation.Formatter = new XmlDeclarationMessageFormatter(dispatchOperation.Formatter);
}
public void Validate(OperationDescription operationDescription)
{
}
}
Then you could specify the IncludeXmlDeclarationAttribute at service operation level, if you need to enable this at service wide level, you could try implementing the IServiceBehavior interface instead.
[ServiceContract]
public interface IDemoService
{
[OperationContract]
[IncludeXmlDeclaration]
[WebGet(UriTemplate = "customers/{name}/")]
Customer GetCustomer(String name);
}