none
The remote server returned an error: (415)

    Question

  • The remote server returned an error: (415) Cannot process the message because the content type 'text/xml; charset=utf-8' was not the expected type 'application/soap+xml; charset=utf-8'..

    I am trying to figure out what I am missing in the following code (NOTE:  I did not use SVCUTIL to generate a CS and APP.CONFIG file - I am looking at doing this purely from code):

        private void Form1_Load(object sender, EventArgs e)
        {
          ChannelFactory<iSync> httpFactory = new ChannelFactory<iSync>(new WSHttpBinding(),
                                         new EndpointAddress(@"http://kab.rivworks.com/services/Sync.svc"));
          try
          {
            iSync myProxy = httpFactory.CreateChannel();
            long clientID = 3;
            bool longmontFord = myProxy.Execute(clientID);
            httpFactory.Close();
          }
          catch (Exception ex)
          {
            httpFactory.Abort();
            textBox1.Text = ex.Message;
            if (ex.InnerException != null)
              textBox2.Text = ex.InnerException.Message;
            else
              textBox2.Text = "n/a";
          }
        }
    
    How do I set the content type from code on the client side?


    Keith Barrows
    Monday, April 26, 2010 11:23 PM

Answers

  • I've got it working now - albeit at a unsecure level.  On this particular web service I am not worried about security as it is mainly used internally (across 2 different untrusted domains), accepts a single LONG and returns a BOOLEAN.  The only risk I see is someone executing it over and over in a Denial of Service attack.  WIll have to look at security a little later.

    My fix is twofold:

    1) Added an override to the wsHttpBinding in the server's web.config.
    2) Changed the binding setup on the client side to match.

    web.config:

     <system.serviceModel>
      <serviceHostingEnvironment aspNetCompatibilityEnabled="false" />
      <behaviors>
       <serviceBehaviors>
        <behavior name="SimpleServiceBehavior">
         <serviceMetadata httpGetEnabled="True" policyVersion="Policy15"/>
        </behavior>
        <behavior name="RivWorks.Web.Service.ServiceBehavior">
         <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
         <serviceMetadata httpGetEnabled="true"/>
         <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
         <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
       </serviceBehaviors>
      </behaviors>
      
      <services>
       <service name="RivWorks.Web.Service.Sync" behaviorConfiguration="RivWorks.Web.Service.ServiceBehavior">
        <endpoint binding="wsHttpBinding" bindingConfiguration="plainWsHttpBinding" contract="RivWorks.Interfaces.Web.Service.ISync" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
       </service>
      </services>
    
      <bindings>
       <wsHttpBinding>
        <binding name="plainWsHttpBinding">
         <security mode="None" />
        </binding>
       </wsHttpBinding>
      </bindings>  
     </system.serviceModel>

    Client code:

    EndpointAddress myEndpoint = new EndpointAddress(@"http://kab.rivworks.com/services/Sync.svc");
    WSHttpBinding myBinding = new WSHttpBinding();
    myBinding.Security.Mode = SecurityMode.None;
    myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
    myBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
    ChannelFactory<iSync> httpFactory = new ChannelFactory<iSync>(myBinding, myEndpoint);
    try
    {
      iSync myProxy = httpFactory.CreateChannel();
      bool longmontFord = myProxy.Execute(clientID);
      httpFactory.Close();
    }
    catch (Exception ex)
    {
      httpFactory.Abort();
    }
    
    So far it is working.  Thanks for the pointers and tips.

     


    Keith Barrows
    • Marked as answer by StarPilot Tuesday, April 27, 2010 7:14 PM
    Tuesday, April 27, 2010 7:14 PM

All replies

  • You'd usually get that error when the client and server bindings are mismatched (the content-type depends on the message version, which is a property of the bindings). How is the binding for the server endpoint setup?
    Monday, April 26, 2010 11:47 PM
  • From what I understand, WCF figures out the content type by looking the properties of the encoder you use. So in your case, you are using Text encoder which is the default one for WSHttpBinding. A quick Reflectoring over System.ServiceModel.Channels.TextMessageEncoderFactory.GetMediaType() tells me it's looking the SOAP envelop version to figure out the content type. AFAIK, default envelop version for WSHttpBinding is SOAP12. So your code should be using application/soap+xml. But according to the error message content type of your message is set to text/xml. 

    Would you be able to enable message logging on the client see what's actually being sent?


    http://www.geeksdiary.com
    Tuesday, April 27, 2010 12:11 AM
  • I will add the web.config when I get back into work tomorrow.

    I'm not sure how to turn on message logging.  Can you point me in the right direction?

    TIA


    Keith Barrows
    Tuesday, April 27, 2010 1:43 AM
  • This link explains how to configure message logging in WCF. 

    http://msdn.microsoft.com/en-us/library/ms730064.aspx

    You could also use either Wireshark or Fiddler to look at the payload without amending the config files.

     

    Cheers,


    http://www.geeksdiary.com
    Tuesday, April 27, 2010 3:46 AM
  •  <system.serviceModel>
      <diagnostics performanceCounters="Default">
       <messageLogging logMalformedMessages="true" logMessagesAtServiceLevel="true"
        logMessagesAtTransportLevel="true" />
      </diagnostics>
      <serviceHostingEnvironment aspNetCompatibilityEnabled="false" />
      <behaviors>
       <endpointBehaviors>
        <behavior name="JsonpServiceBehavior">
         <webHttp />
        </behavior>
       </endpointBehaviors>
       <serviceBehaviors>
        <behavior name="SimpleServiceBehavior">
         <serviceMetadata httpGetEnabled="True" policyVersion="Policy15"/>
        </behavior>
        <behavior name="RivWorks.Web.Service.ServiceBehavior">
         <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
         <serviceMetadata httpGetEnabled="true"/>
         <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
         <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
       </serviceBehaviors>
      </behaviors>
      
      <services>
       <service name="RivWorks.Web.Service.NegotiateService" behaviorConfiguration="SimpleServiceBehavior">
        <endpoint address=""
             binding="customBinding"
             bindingConfiguration="jsonpBinding"
             behaviorConfiguration="JsonpServiceBehavior"
             contract="RivWorks.Web.Service.NegotiateService" />
        <endpoint address="mex"
             binding="mexHttpBinding"
             contract="RivWorks.Web.Service.NegotiateService" />
       </service>
       <service name="RivWorks.Web.Service.Sync" behaviorConfiguration="RivWorks.Web.Service.ServiceBehavior">
        <endpoint address="" binding="wsHttpBinding" contract="RivWorks.Interfaces.Web.Service.ISync" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
       </service>
      </services>
    
      <extensions>
       <bindingElementExtensions>
        <add name="jsonpMessageEncoding" type="RivWorks.Web.Service.JSONPBindingExtension, RivWorks.Web.Service, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
       </bindingElementExtensions>
      </extensions>
    
      <bindings>
       <customBinding>
        <binding name="jsonpBinding" >
         <jsonpMessageEncoding />
         <httpTransport manualAddressing="true"/>
        </binding>
       </customBinding>
      </bindings>  
     </system.serviceModel>

    I'm not seeing anything obvious in here.  It is using wsHttpBinding.  I'm not sure what controls the text encoding though.  Regardless, I need to figure out how to control that on the client side.

     

    TIA


    Keith Barrows
    Tuesday, April 27, 2010 3:11 PM
  • Added the tracking and have twiddled a little bit of code.  Now I am getting another error - which is actually a step in the right direction...

    The caller was not authenticated by the service.
    The request for security token could not be satisfied because authentication failed.

    I'm playing around with the client side bindings but have not quite figured them all out yet.

        private void Form1_Load(object sender, EventArgs e)
        {
          EndpointAddress myEndpoint = new EndpointAddress(@"http://kab.rivworks.com/services/Sync.svc");
          WSHttpBinding myBinding = new WSHttpBinding();
          myBinding.Security.Mode = SecurityMode.Message;
          myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
          myBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
    
          ChannelFactory<iSync> httpFactory = new ChannelFactory<iSync>(myBinding, myEndpoint);
          try
          {
            iSync myProxy = httpFactory.CreateChannel();
            long clientID = 3;
            bool longmontFord = myProxy.Execute(clientID);
            httpFactory.Close();
            textBox1.Text = "Result = " + longmontFord.ToString();
            textBox2.Text = "No Errors";
          }
          catch (Exception ex)
          {
            httpFactory.Abort();
            textBox1.Text = ex.Message;
            if (ex.InnerException != null)
              textBox2.Text = ex.InnerException.Message;
            else
              textBox2.Text = "n/a";
          }
        }
    


    Keith Barrows
    Tuesday, April 27, 2010 3:36 PM
  • Here is the latest trace:

    <E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
     <System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
      <EventID>0</EventID>
      <Type>3</Type>
      <SubType Name="Information">0</SubType>
      <Level>8</Level>
      <TimeCreated SystemTime="2010-04-27T15:37:37.5436543Z" />
      <Source Name="System.ServiceModel.MessageLogging" />
      <Correlation ActivityID="{9f32d2a6-0997-4940-a626-3cff5465fa63}" />
      <Execution ProcessName="w3wp" ProcessID="6104" ThreadID="18" />
      <Channel />
      <Computer>BUNKHOUSE</Computer>
     </System>
     <ApplicationData>
      <TraceData>
       <DataItem>
        <MessageLogTraceRecord Time="2010-04-27T09:37:37.5436543-06:00" Source="ServiceLevelSendReply" Type="System.ServiceModel.Channels.BodyWriterMessage" xmlns="http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace">
         <s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
          <s:Header>
           <a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/soap/fault</a:Action>
           <a:RelatesTo>urn:uuid:248292ec-8d8d-4cfc-ac4b-b940f8838d02</a:RelatesTo>
           <ActivityId CorrelationId="aa0e7399-28df-4c81-a753-92bb718e26e1" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">9f32d2a6-0997-4940-a626-3cff5465fa63</ActivityId>
          </s:Header>
          <s:Body>
           <s:Fault>
            <s:Code>
             <s:Value>s:Sender</s:Value>
             <s:Subcode>
              <s:Value xmlns:a="http://schemas.xmlsoap.org/ws/2005/02/trust">a:FailedAuthentication</s:Value>
             </s:Subcode>
            </s:Code>
            <s:Reason>
             <s:Text xml:lang="en-US">The request for security token could not be satisfied because authentication failed.</s:Text>
            </s:Reason>
           </s:Fault>
          </s:Body>
         </s:Envelope>
        </MessageLogTraceRecord>
       </DataItem>
      </TraceData>
     </ApplicationData>
    </E2ETraceEvent>


    Keith Barrows
    Tuesday, April 27, 2010 3:40 PM
  • I've got it working now - albeit at a unsecure level.  On this particular web service I am not worried about security as it is mainly used internally (across 2 different untrusted domains), accepts a single LONG and returns a BOOLEAN.  The only risk I see is someone executing it over and over in a Denial of Service attack.  WIll have to look at security a little later.

    My fix is twofold:

    1) Added an override to the wsHttpBinding in the server's web.config.
    2) Changed the binding setup on the client side to match.

    web.config:

     <system.serviceModel>
      <serviceHostingEnvironment aspNetCompatibilityEnabled="false" />
      <behaviors>
       <serviceBehaviors>
        <behavior name="SimpleServiceBehavior">
         <serviceMetadata httpGetEnabled="True" policyVersion="Policy15"/>
        </behavior>
        <behavior name="RivWorks.Web.Service.ServiceBehavior">
         <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
         <serviceMetadata httpGetEnabled="true"/>
         <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
         <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
       </serviceBehaviors>
      </behaviors>
      
      <services>
       <service name="RivWorks.Web.Service.Sync" behaviorConfiguration="RivWorks.Web.Service.ServiceBehavior">
        <endpoint binding="wsHttpBinding" bindingConfiguration="plainWsHttpBinding" contract="RivWorks.Interfaces.Web.Service.ISync" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
       </service>
      </services>
    
      <bindings>
       <wsHttpBinding>
        <binding name="plainWsHttpBinding">
         <security mode="None" />
        </binding>
       </wsHttpBinding>
      </bindings>  
     </system.serviceModel>

    Client code:

    EndpointAddress myEndpoint = new EndpointAddress(@"http://kab.rivworks.com/services/Sync.svc");
    WSHttpBinding myBinding = new WSHttpBinding();
    myBinding.Security.Mode = SecurityMode.None;
    myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
    myBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
    ChannelFactory<iSync> httpFactory = new ChannelFactory<iSync>(myBinding, myEndpoint);
    try
    {
      iSync myProxy = httpFactory.CreateChannel();
      bool longmontFord = myProxy.Execute(clientID);
      httpFactory.Close();
    }
    catch (Exception ex)
    {
      httpFactory.Abort();
    }
    
    So far it is working.  Thanks for the pointers and tips.

     


    Keith Barrows
    • Marked as answer by StarPilot Tuesday, April 27, 2010 7:14 PM
    Tuesday, April 27, 2010 7:14 PM