title: Why is my WCF proxy sending JSON with Content-Type: application/xml?
body: <h2>Summary</h2>
  
  <p>I have a WCF backend service running in an Azure app service, and I'm developing a proxy which will use the same interface but manipulate some messages for compatibility with a client's system. I know this is a bit vague, but the details aren't important.</p>
  
  <p>The problem is that when the proxy, running in IIS Express from Visual Studio 17, calls the backend it is doing so incorrectly, and the backend rejects the request. (Curiously the precise nature of the rejection differs between the real service and the minimal reproducible test case I've created for this post, but the difference is late enough that I don't believe it to be relevant).</p>
  
  <p>By adding trace listeners to <code>System.Net</code> I can observe that the call made by the proxy to the backend has a body in JSON but headers which claim that it's XML:</p>
  
  <pre class="lang-none prettyprint-override"><code>System.Net Verbose: 0 : [4140] Data from ConnectStream#29742526::Write
  System.Net Verbose: 0 : [4140] 00000000 : 7B 22 42 61 72 22 3A 22-42 2D 50 72 6F 78 69 65 : {"Bar":"B-Proxie
  System.Net Verbose: 0 : [4140] 00000010 : 64 22 2C 22 46 6F 6F 22-3A 22 41 22 7D          : d","Foo":"A"}
  System.Net Verbose: 0 : [4140] Exiting ConnectStream#29742526::Write() 
  System.Net Verbose: 0 : [4140] Entering ConnectStream#29742526::Close()
  System.Net Verbose: 0 : [4140] Exiting ConnectStream#29742526::Close() 
  System.Net Verbose: 0 : [4140] Entering HttpWebRequest#45658036::GetResponse()
  System.Net Information: 0 : [4140] HttpWebRequest#45658036 - Request: POST /DemoService.svc/DoTheThing HTTP/1.1
  
  System.Net Information: 0 : [4140] ConnectStream#29742526 - Sending headers
  {
  Content-Type: application/xml; charset=utf-8
  Host: wcfproxydemo.azurewebsites.net
  Content-Length: 29
  Expect: 100-continue
  Accept-Encoding: gzip, deflate
  Connection: Close
  }.
  </code></pre>
  
  <p><strong>Can I change some configuration to get it to send JSON with the correct Content-Type header?</strong> I'd prefer not to have to switch everything over to XML.</p>
  
  <h2>Details</h2>
  
  <p>My minimal reproducible test case is <a href="https://github.com/pjt33/WcfDemo" rel="nofollow noreferrer">available on Github</a>. The only thing I've elided there is the publish profile to push the backend to Azure.</p>
  
  <p>The various projects share an interface project, and there's no auto-generated service reference. (That might be a possible way forward, but it seems rather heavy-weight, so I'd prefer a config-based solution). The WCF config for the three components is</p>
  
  <h3>Backend</h3>
  
  <pre class="lang-xml prettyprint-override"><code>  &lt;system.serviceModel&gt;
      &lt;bindings&gt;
        &lt;customBinding&gt;
          &lt;binding name="rest-https-nokeepalive"&gt;
            &lt;webMessageEncoding /&gt;
            &lt;httpsTransport manualAddressing="true" allowCookies="false" keepAliveEnabled="false" maxBufferSize="10000000" maxReceivedMessageSize="10000000" maxBufferPoolSize="10000000" /&gt;
          &lt;/binding&gt;
        &lt;/customBinding&gt;
      &lt;/bindings&gt;
      &lt;services&gt;
        &lt;service name="Backend.DemoService" behaviorConfiguration="ServiceBehaviour"&gt;
          &lt;endpoint binding="customBinding" bindingConfiguration="rest-https-nokeepalive" contract="Interface.IDemoService" behaviorConfiguration="web" /&gt;
        &lt;/service&gt;
      &lt;/services&gt;
      &lt;behaviors&gt;
        &lt;serviceBehaviors&gt;
          &lt;behavior name="ServiceBehaviour"&gt;
            &lt;serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" /&gt;
            &lt;serviceDebug includeExceptionDetailInFaults="true" /&gt;
          &lt;/behavior&gt;
        &lt;/serviceBehaviors&gt;
        &lt;endpointBehaviors&gt;
          &lt;behavior name="web"&gt;
            &lt;webHttp /&gt;
          &lt;/behavior&gt;
        &lt;/endpointBehaviors&gt;
      &lt;/behaviors&gt;
      &lt;serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" /&gt;
    &lt;/system.serviceModel&gt;
  </code></pre>
  
  <h3>Proxy</h3>
  
  <pre class="lang-xml prettyprint-override"><code>  &lt;system.serviceModel&gt;
      &lt;bindings&gt;
        &lt;customBinding&gt;
          &lt;binding name="rest-https-nokeepalive"&gt;
            &lt;webMessageEncoding /&gt;
            &lt;httpsTransport manualAddressing="true" allowCookies="false" keepAliveEnabled="false" maxBufferSize="10000000" maxReceivedMessageSize="10000000" maxBufferPoolSize="10000000" /&gt;
          &lt;/binding&gt;
        &lt;/customBinding&gt;
      &lt;/bindings&gt;
      &lt;services&gt;
        &lt;service name="Proxy.DemoService" behaviorConfiguration="ServiceBehaviour"&gt;
          &lt;endpoint binding="customBinding" bindingConfiguration="rest-https-nokeepalive" contract="Interface.IDemoService" behaviorConfiguration="web" /&gt;
        &lt;/service&gt;
      &lt;/services&gt;
      &lt;client&gt;
        &lt;endpoint name="Backend" address="https://wcfproxydemo.azurewebsites.net/DemoService.svc" binding="customBinding" bindingConfiguration="rest-https-nokeepalive" contract="Interface.IDemoService" behaviorConfiguration="web" /&gt;
      &lt;/client&gt;
      &lt;behaviors&gt;
        &lt;serviceBehaviors&gt;
          &lt;behavior name="ServiceBehaviour"&gt;
            &lt;serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" /&gt;
            &lt;serviceDebug includeExceptionDetailInFaults="true" /&gt;
          &lt;/behavior&gt;
        &lt;/serviceBehaviors&gt;
        &lt;endpointBehaviors&gt;
          &lt;behavior name="web"&gt;
            &lt;webHttp /&gt;
          &lt;/behavior&gt;
        &lt;/endpointBehaviors&gt;
      &lt;/behaviors&gt;
      &lt;serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" /&gt;
      &lt;diagnostics&gt;
        &lt;messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" maxMessagesToLog="3000" maxSizeOfMessageToLog="2000" /&gt;
      &lt;/diagnostics&gt;
    &lt;/system.serviceModel&gt;
  </code></pre>
  
  <h3>Test frontend</h3>
  
  <pre class="lang-xml prettyprint-override"><code>  &lt;system.serviceModel&gt;
      &lt;bindings&gt;
        &lt;customBinding&gt;
          &lt;binding name="rest-https-nokeepalive"&gt;
            &lt;webMessageEncoding /&gt;
            &lt;httpsTransport manualAddressing="true" allowCookies="false" keepAliveEnabled="false" maxBufferSize="10000000" maxReceivedMessageSize="10000000" maxBufferPoolSize="10000000" /&gt;
          &lt;/binding&gt;
        &lt;/customBinding&gt;
      &lt;/bindings&gt;
      &lt;client&gt;
        &lt;endpoint name="Direct" address="https://wcfproxydemo.azurewebsites.net/DemoService.svc" binding="customBinding" bindingConfiguration="rest-https-nokeepalive" contract="Interface.IDemoService" behaviorConfiguration="web" /&gt;
        &lt;endpoint name="Proxied" address="https://localhost:44388/DemoService.svc" binding="customBinding" bindingConfiguration="rest-https-nokeepalive" contract="Interface.IDemoService" behaviorConfiguration="web" /&gt;
      &lt;/client&gt;
      &lt;behaviors&gt;
        &lt;endpointBehaviors&gt;
          &lt;behavior name="web"&gt;
            &lt;webHttp /&gt;
          &lt;/behavior&gt;
        &lt;/endpointBehaviors&gt;
      &lt;/behaviors&gt;
      &lt;diagnostics&gt;
        &lt;messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" maxMessagesToLog="3000" maxSizeOfMessageToLog="2000"/&gt;
      &lt;/diagnostics&gt;
    &lt;/system.serviceModel&gt;
  </code></pre>
  
  <p>A direct connection from the frontend to the backend works fine. A proxied connection fails because the backend isn't happy with the request it receives from the proxy, for obvious reasons.</p>