views:

1615

answers:

3

Hello there,

I have now investigated the 400 - BadRequest code for the last two hours. A lot of sugestions goes towards ensuring the bindingConfiguration attribute is set correctly, and in my case, it is.

Now, I need YOUR help before destroying the building i am in :-)

I run a WCF RestFull service (very lightweight, using this resource for inspiration: http://msdn.microsoft.com/en-us/magazine/dd315413.aspx) which (for now) accepts an XmlElement (POX) provided through the POST verb.

I am currently ONLY using Fiddler's request builder before implementing a true client (as this is mixed environments).

When I do this for XML smaller than 65K, it works fine - larger, it throws this exception: 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.

Here is my web.config file (which I even included the client-tag for (desperate times!)):

<system.web>
    <httpRuntime maxRequestLength="1500000" executionTimeout="180"/>
  </system.web>
  <system.serviceModel>
    <diagnostics>
      <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
    </diagnostics>
    <bindings>
      <webHttpBinding>
        <binding name="WebHttpBinding" maxReceivedMessageSize="1500000" maxBufferPoolSize="1500000" maxBufferSize="1500000" closeTimeout="00:03:00" openTimeout="00:03:00" receiveTimeout="00:10:00" sendTimeout="00:03:00">
          <readerQuotas maxStringContentLength="1500000" maxArrayLength="1500000" maxBytesPerRead="1500000" />
          <security mode="None"/>
        </binding>
      </webHttpBinding>
    </bindings>
    <client>
      <endpoint address="" binding="webHttpBinding" bindingConfiguration="WebHttpBinding" contract="Commerce.ICatalogue"/>
    </client>
    <services>
      <service behaviorConfiguration="ServiceBehavior" name="Catalogue">
        <endpoint address="" 
                  behaviorConfiguration="RestFull" 
                  binding="webHttpBinding"
                  bindingConfiguration="WebHttpBinding" 
                  contract="Commerce.ICatalogue" />
        <!-- endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" / -->
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="RestFull">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true"/>
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

Thanks in advance for any help leading to succesfull call with >65K XML ;-)

A: 

This is a blog entry I wrote that reproduces this problem with an absolutely minimal WCF server and client piece:

WCF - Fixing client side string length exceptions

In particular, you may need a Custom Binding Configuration. At least reproducing this sample may give you some ideas for your particular situation.

Michael Maddox
Hi Michael,Thank you for your input.Allthough your article is interesting, my challenge so far is to get it to work with Fiddler. I assume that no fiddler.config exists, so I have no client settings to set, which should not matter, as I am quite sure, that Fiddler does not have a limitation.Am I wrong here?
Michael Mortensen
So it's working fine using a command line or other .NET client program? I would have no idea how to tweak Fiddler, but if you've verified your server side can handle > 65k, the problem is definitely on the Fiddler side.
Michael Maddox
The challenge is, that this is a down-to-earth lightweight WCF implementation using the WebServiceHostFactory class. As far as I understand, this means, that I cannot "Add a service reference" because it requires the WSDL format (why i did not continue with your otherwise excellent link).
Michael Mortensen
Try renaming your binding from WebHttpBinding to WebHttpBindingConfiguration and then updating your endpoint to use the new name. See also step 3 here: http://msdn.microsoft.com/en-us/library/ms733051.aspx . I don't know if that will fix the problem, but it's certainly giving me a headache to look at. :)
Michael Maddox
I found the issue; after some heavily research and no good answers on the net, I rethought the implementation in regards to the WebServiceHostFactory. Since this can be used WITHOUT the ServiceModel config entry, I doubt it ever reads from it.So I changed the implementation, and will document this in this thread so others as frustrated as me, can find a quick fix.Thanks for your help though :-)
Michael Mortensen
+2  A: 

All right, this one really caused me a hard time resolving, which I will spare others for. The challenge was in the fact, that I used the <%@ ServiceHost Factory="System.ServiceModel.Activation.WebServiceHostFactory" Service="fullyQualifiedClassName" %>, which is a nice and easy factory implementation approach.

However, this approach has it drawbacks; since no configuration is needed in the web.config file, the WebServiceHostFactory class by design does not ever read from the web.config file. I know; I could inherit from this class, and make the appropriate changes so it may indeed read from the config file, but this seemed a little out of scope.

My solution was to go back to the more traditional way of implementing the WCF; <%@ ServiceHost Service="fullyQualifiedClassName" CodeBehind="~/App_Code/Catalogue.cs" %>, and then use my already configured values in the web.config file.

Here is my modified web.config file (with respect to Maddox headache):

  <system.serviceModel>
<bindings>
  <webHttpBinding>
    <binding name="XmlMessageBinding" maxReceivedMessageSize="5000000" maxBufferPoolSize="5000000" maxBufferSize="5000000" closeTimeout="00:03:00" openTimeout="00:03:00" receiveTimeout="00:10:00" sendTimeout="00:03:00">
      <readerQuotas maxStringContentLength="5000000" maxArrayLength="5000000" maxBytesPerRead="5000000" />
      <security mode="None"/>
    </binding>
  </webHttpBinding>
</bindings>
<services>
  <service name="fullyQualifiedClassName" behaviorConfiguration="DevelopmentBehavior">
    <endpoint name="REST" address="" binding="webHttpBinding" contract="fullyQualifiedInterfaceName" behaviorConfiguration="RestEndpointBehavior" bindingConfiguration="XmlMessageBinding" />
  </service>
</services>
<behaviors>
  <endpointBehaviors>
    <behavior name="RestEndpointBehavior">
      <webHttp/>
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="DevelopmentBehavior">
      <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true"/>
      <serviceMetadata httpGetEnabled="true"/>
    </behavior>
    <behavior name="ProductionBehavior">
      <serviceDebug httpHelpPageEnabled="false" includeExceptionDetailInFaults="false"/>
      <serviceMetadata httpGetEnabled="false"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

Another benefit of this change is, that you can now reference your WCF-rest service directly from .NET; this cannot be done using the Factory model and my implementation of XmlElement through out the solution.

I hope this can help others with similar issues ...

Michael Mortensen
A: 

Hi I tried the above modified code,its not working for my code,suggest me how to solve this issue.............................

I would gladly help, but can you be more specific in regards to your issues? Did you pay attention to my comments regarding the Factory implementation?
Michael Mortensen