Change the response output format in XML and JSON only for webHttpBinding
<p>I've been working on this problem for quite a long time, here are my findings and requirements:</p>

<p>We have two endpoints:</p>

<ul>
<li>TCP endpoint</li>
<li>WebHttp endpoint</li>
</ul>

<p>Through the WebHttp endpoint, we need to support JSON and XML but with a custom response format. This is the format needed (only JSON shown for clarity):</p>

<pre><code>{
    "status": "success",
    "data" : {}
}
</code></pre>

<p>What we need is for each object returned to be serialized normally and be put under data in the hierarchy. Let's say we have this <code>OperationContract</code>:</p>

<pre><code>ObjectToBeReturned test();
</code></pre>

<p>and <code>ObjectToBeReturned</code> is:</p>

<pre><code>[DataContract]
class ObjectToBeReturned {
    [DataMember]
    public string A {get; set;}
    [DataMember]
    public string B {get; set;}
}
</code></pre>

<p>Now, we would like through <code>TCP</code> to exchange directly the <code>ObjectToBeReturned</code> object but through <code>WebHttp</code> to have the following format as a response:</p>

<pre><code>{
    "status": "success",
    "data": {
        "A": "atest",
        "B": "btest"
    }
}
</code></pre>

<p><strong>Possibility 1</strong></p>

<p>We have considered two possibilities. The first one would be to have an object say named Response that would be the return object of all our <code>OperationContract</code> and it would contain the following:</p>

<pre><code>[DataContract]
class Response&lt;T&gt; {
    [DataMember]
    public string Status {get; set;}
    [DataMember]
    public T Data {get; set;}
}
</code></pre>

<p>The problem with that is we would be required to exchange this object also through the TCP protocol but that is not our ideal scenario.</p>

<p><strong>Possibility 2</strong></p>

<p>We have tried to add a custom <code>EndpointBehavior</code> with a custom <code>IDispatchMessageFormatter</code> that would only be present for the <code>WebHttp</code> endpoint.</p>

<p>In this class, we implemented the following method:</p>

<pre><code> public Message SerializeReply(
            MessageVersion messageVersion,
            object[] parameters,
            object result)
        {

            var clientAcceptType = WebOperationContext.Current.IncomingRequest.Accept;

            Type type = result.GetType();

            var genericResponseType = typeof(Response&lt;&gt;);
            var specificResponseType = genericResponseType.MakeGenericType(result.GetType());
            var response = Activator.CreateInstance(specificResponseType, result);

            Message message;
            WebBodyFormatMessageProperty webBodyFormatMessageProperty;


            if (clientAcceptType == "application/json")
            {
                message = Message.CreateMessage(messageVersion, "", response, new DataContractJsonSerializer(specificResponseType));
                webBodyFormatMessageProperty = new WebBodyFormatMessageProperty(WebContentFormat.Json);

            }
            else
            {
                message = Message.CreateMessage(messageVersion, "", response, new DataContractSerializer(specificResponseType));
                webBodyFormatMessageProperty = new WebBodyFormatMessageProperty(WebContentFormat.Xml);

            }

            var responseMessageProperty = new HttpResponseMessageProperty
            {
                StatusCode = System.Net.HttpStatusCode.OK
            };

            message.Properties.Add(HttpResponseMessageProperty.Name, responseMessageProperty);

            message.Properties.Add(WebBodyFormatMessageProperty.Name, webBodyFormatMessageProperty); 
            return message;
        }
</code></pre>

<p>This seems really promising. The problem with that method is that when serializing with the <code>DataContractSerializer</code> we get the following error:</p>

<blockquote>
  <p>Consider using a DataContractResolver if you are using
  DataContractSerializer or add any types not known statically to the
  list of known types - for example, by using the KnownTypeAttribute
  attribute or by adding them to the list of known types passed to the
  serializer.</p>
</blockquote>

<p>We really don't want to list all of our known types above our Response class since there will be too many and maintenance will be a nightmare (when we listed the knowntypes we were able to get the data). Please note that all the objects passed to response will be decorated with a <code>DataContract</code> attribute.</p>

<p>I have to mention that we don't care if changing the message format can cause the <code>WebHttp</code> endpoint to not be accessible via a <code>ServiceReference</code> in another C# project, they should use <code>TCP</code> for that.</p>

<p><strong>Questions</strong></p>

<p>Basically, we only want to customize the return format for WebHttp so, the questions are:</p>

<ul>
<li>Is there an easier way to accomplish that than what we are doing?</li>
<li>Is there a way to tell the serializer the knowntype from the <code>result</code> parameter's type in the <code>SerializeReply</code> method?</li>
<li>Should we implement a custom <code>Serializer</code> that will be called in the <code>MessageDispatcherFormatter</code> that will tweak the format to fit ours ?</li>
</ul>

<p>We feel we are on the right path but some parts are missing.</p>