none
Error code 400 Bad Request trying to transfer byte array from client to server

    Question

  • Hello, I am trying to transfer an image as a byte array from client to server, but unfortunately I am getting an error code 400 Bad Request.  The service is working fine for other methods that take ints or strings, but the byte array parameter is causing a problem.  I have spent the day trawling similar posts and upping message sizes etc.  If anyone could help spot the problem here that'd be great.

    The error is a Protocol Exception - The remote server returned an unexpected response: (400) Bad Request.

    Client gets the ChannelFactory constructed using the below code, then calls the method passing in the byte array:

    public class ChannelFactoryHelper
        {
            private static int MAX_SIZE = 2147483647;//131072;
     
            public static IScanFactoryService GetScanFactoryService(string sServiceURL)
            {
                return ChannelFactory<IScanFactoryService>.CreateChannel(GetDefaultBinding(), new EndpointAddress(sServiceURL));
            }
     
            private static BasicHttpBinding GetDefaultBinding()
            {
                BasicHttpBinding oBasicHttpBinding = new BasicHttpBinding();
                oBasicHttpBinding.MaxBufferSize = MAX_SIZE;
                oBasicHttpBinding.MaxReceivedMessageSize = MAX_SIZE;
                oBasicHttpBinding.MaxBufferPoolSize = MAX_SIZE;
                oBasicHttpBinding.ReaderQuotas.MaxArrayLength = MAX_SIZE;
                oBasicHttpBinding.ReaderQuotas.MaxStringContentLength = MAX_SIZE;
                return oBasicHttpBinding;
            }
    

    My server web.config looks like this:

    <?xml version="1.0"?>
    <configuration>
      <configSections>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
          <section name="ScanFactoryService.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </sectionGroup>
      </configSections>
      <connectionStrings>
        <add name="ScanFactoryEntities" connectionString="metadata=res://*/ScanFactoryModel.csdl|res://*/ScanFactoryModel.ssdl|res://*/ScanFactoryModel.msl;provider=System.Data.SqlClient;provider connection string='data source=localhost;initial catalog=deleted;user id=deleted;password=deleted;multipleactiveresultsets=True;App=EntityFramework'" providerName="System.Data.EntityClient" />
      </connectionStrings>
      <system.web>
        <!--<httpRuntime maxRequestLength="2147483647" />-->
        <compilation debug="true" targetFramework="4.0" />
      </system.web>
      <system.serviceModel>
        <services>
          <service name="ScanFactoryService">
            <endpoint address="http://localhost:4033/ScanFactoryService.svc" binding="basicHttpBinding" 
                      contract="Application.ScanFactory.Contracts.ServiceContracts.IScanFactoryService" 
                      bindingConfiguration="BasicHttpBinding_IScanFactoryService" name="ScanFactoryService" />
          </service>
        </services>
        <bindings>
          <basicHttpBinding>
            <binding name="BasicHttpBinding_IScanFactoryService" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
              <readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647" />
              <security mode="None">
                <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
              </security>
            </binding>
          </basicHttpBinding>
        </bindings>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <!-- 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"/>
              <errorHandler />          
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <extensions>
          <behaviorExtensions>
            <add name="errorHandler" type="DistributedServices.ScanFactoryService.ScanFactoryServiceExceptionHandlerElement, DistributedServices.ScanFactoryService" />
          </behaviorExtensions>
        </extensions>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
      </system.serviceModel>
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
      </system.webServer>
      <applicationSettings>
        <ScanFactoryService.Properties.Settings>
          <setting name="ErrorLogFilePath" serializeAs="String">
            <value>E:\Depot\ScanFactory\ScanFactoryService\Error.log</value>
          </setting>
        </ScanFactoryService.Properties.Settings>
      </applicationSettings>
    </configuration>

    Any ideas?

    Thanks,

    John

    Friday, June 08, 2012 4:01 PM

Answers

  • The name attribute of the <service> element must contain the fully-qualified name of the service class. Your contract class is named Application.ScanFactory.Contracts.ServiceContracts.IScanFactoryService - if the service class is in the same namespace, then you should have that in the

     <services>
       <service name="Application.ScanFactory.Contracts.ServiceContracts.ScanFactoryService">
         <endpoint address="http://localhost:4033/ScanFactoryService.svc" binding="basicHttpBinding"
                   contract="Application.ScanFactory.Contracts.ServiceContracts.IScanFactoryService"
                   bindingConfiguration="BasicHttpBinding_IScanFactoryService" name="ScanFactoryService" />
       </service>
     </services>


    Carlos Figueira

    • Marked as answer by JCorker Monday, June 11, 2012 10:20 AM
    Friday, June 08, 2012 11:25 PM

All replies

  • Here are a couple things that I can think of :

    1) Are you trying to send large images through WCF? It might exceed the the MAX_SIZE

    2) Have you tried using a messageEncoding format like MTOM ?

    Prashanthi.

    Friday, June 08, 2012 4:44 PM
  • Hi,

    I should have said I am sending images that are about 60kb, as you can see I have tried setting the message sizes to large numbers to rule that out as a possibility unless you can see one that I have missed?

    I haven't tried MTOM, do you think this would make a difference with the error I am seeing?  I understand it can cut down transmission size of large binary objects.

    John

    Friday, June 08, 2012 5:23 PM
  • The name attribute of the <service> element must contain the fully-qualified name of the service class. Your contract class is named Application.ScanFactory.Contracts.ServiceContracts.IScanFactoryService - if the service class is in the same namespace, then you should have that in the

     <services>
       <service name="Application.ScanFactory.Contracts.ServiceContracts.ScanFactoryService">
         <endpoint address="http://localhost:4033/ScanFactoryService.svc" binding="basicHttpBinding"
                   contract="Application.ScanFactory.Contracts.ServiceContracts.IScanFactoryService"
                   bindingConfiguration="BasicHttpBinding_IScanFactoryService" name="ScanFactoryService" />
       </service>
     </services>


    Carlos Figueira

    • Marked as answer by JCorker Monday, June 11, 2012 10:20 AM
    Friday, June 08, 2012 11:25 PM
  • Excellent, thank you for pointing that out.  Things appear to working fine now.
    Monday, June 11, 2012 10:21 AM