Solving development problems  |  About this blog

Archive for the ‘web.config’ tag

Increasing maximum request length for WCF REST Web Service with ASP .NET 4.0

Recently we have extended a web service with method for uploading user’s profile image. So far the service was working fine with less amount of data, i.e. name, address and description. First image upload test with the new method resulted with 400 Bad Request. Breakpoints were set in WCF method but debugger did not stop there, not even entered the method.

Default configuration

WCF service had been configured for REST using default webHttpBinding configuration in web.config

<configuration>
  ...
  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="ApiBehavior" />
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="Avivo.Web.Services.ApiServiceBehavior">
         <serviceMetadata httpGetEnabled="true" />
         <serviceDebug includeExceptionDetailInFaults="false" />
         <serviceTimeouts transactionTimeout="00:05:00" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <services>
      <!-- API v1.0 -->
      <service behaviorConfiguration="Avivo.Web.Services.ApiServiceBehavior"
name="Avivo.Web.Services.ApiService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:1234/api/v1" />
          </baseAddresses>
        </host>
        <endpoint address="" binding="webHttpBinding"
contract="Avivo.Web.Services.IApiService" behaviorConfiguration="ApiBehavior" />
      </service>
    </services>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true">
      <baseAddressPrefixFilters>
        <add prefix="http://localhost:1234/api/v1"/>
      </baseAddressPrefixFilters>
    </serviceHostingEnvironment>

  </system.serviceModel>
  ...
</configuration>

Identifying the problem

Images can be quite large (few MB), especially when comparing with text size (few KB). At first it was assumed the web service call has exceeded maximum request length limit. To confirm the assumption we analyzed WCF traffic using SvcTraceViewer.

Enabling WCF tracing in web.config

<configuration>
  ...
  <!-- Use SvcTraceViewer for debugging WCF services -->
  <system.diagnostics>
    <trace autoflush="true" />
    <sources>
      <source name="System.ServiceModel" switchValue="Information,
ActivityTracing" propagateActivity="true">
        <listeners>
          <add name="sdt" type="System.Diagnostics.XmlWriterTraceListener"
initializeData="d:\temp\wcf-trace.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
  ...
</configuration>

When the tracing is set each request to web service will write entry to d:\temp\wcf-trace.svclog in this case. The report file can be opened with SvcTraceViewer found in %ProgramFiles%\Microsoft SDKs\Windows, e.g. “c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\SvcTraceViewer.exe”

Entries in SvcTraceViewer marked with red represents errors. The problematic request was logged with error message:

The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element.

Identifying that assumption was right and the upload request exceeded default 65 KB limit.

Increasing request limit quota

Customizing webHttpBinding in web.config and referencing with bindingConfiguration in endpoint element

<configuration>
        ...
  <system.serviceModel>
        ...
    <bindings>
      <!-- Customizations for REST service -->
      <webHttpBinding>
        <!-- Limits set to 10 MB (specified value in bytes) -->
        <binding name="ApiQuotaBinding" maxReceivedMessageSize="10485760"
maxBufferPoolSize="10485760" maxBufferSize="10485760" closeTimeout="00:03:00"
openTimeout="00:03:00" receiveTimeout="00:10:00" sendTimeout="00:03:00">
          <readerQuotas maxDepth="32" maxStringContentLength="10485760"
maxArrayLength="10485760" maxBytesPerRead="10485760" />
          <security mode="None" />
        </binding>
      </webHttpBinding>
    </bindings>

    <services>
      <!-- API v1.0 -->
      <service behaviorConfiguration="Avivo.Web.Services.ApiServiceBehavior"
name="Avivo.Web.Services.ApiService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:1234/api/v1" />
          </baseAddresses>
        </host>
        <!-- Added attribute 'bindingConfiguration' -->
        <endpoint address="" bindingConfiguration="ApiQuotaBinding" binding="webHttpBinding"
contract="Avivo.Web.Services.IApiService" behaviorConfiguration="ApiBehavior" />
      </service>
    </services>

  </system.serviceModel>
  ...
</configuration>

Additionally httpRuntime limits must also be set because web service is running in ASP .NET compatibilty mode. Note that maxRequestLength has value in kilobytes.

<configuration>
  ...
  <system.web>
    <httpRuntime maxRequestLength="10240" />
  </system.web>
  ...
</configuration>

Testing

Finding the solution was not straightforward, it took some time searching the web and reading documentation. Finally after figuring out the described config in this post we solved the problem with success.

Written by developer

October 26th, 2011 at 7:50 pm

Allowing WCF services (svc extension) in IIS7

  1. First, click on your website (or IIS7 website root)
  2. Click on MimeTypes and enter “.svc” and “application/octet-stream” and save
  3. In your project add this to your web.config in <httpHandlers> section:
    <add name=”svc-Integrated” path=”*.svc” verb=”*” type=”System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089″ preCondition=”integratedMode” />
    <add name=”svc-ISAPI-2.0″ path=”*.svc” verb=”*” modules=”IsapiModule” scriptProcessor=”%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll” preCondition=”classicMode,runtimeVersionv2.0,bitness32″ />

Written by Avivo

July 12th, 2010 at 9:17 pm