locked
400 - Bad Request: 64K Restriction RRS feed

  • Question

  • Hi,

     

    Believing to have set all properties to max, I keep on getting the 400 -  Bad Request from my Data Service host.
    As soon as I try to send over 64+KB of entity data over from my client to my Data Service host, this happens.

     

    That's even before

    Code Snippet
    Protected Overrides Sub OnStartProcessingRequest(ByVal args As System.Data.Services.ProcessRequestArgs)

     

    or

    Code Snippet
    Protected Overrides Sub HandleException(ByVal args As System.Data.Services.HandleExceptionArgs)

     

    of the Data Service are invoked.

     

    The host and client are both console applications, no IIS is involved.
    The project only uses the proxy code from the "Add Service Reference" at the client.
    The rest, communication settings and the likes, needs to be done completely in code (so, no .config files).


    The data service in short:

    Code Snippet
    Public Class BusinessEntityDataService : Inherits DataService(Of BusinessEntities)


      Public Shared Sub InitializeService(ByVal Conf As IDataServiceConfiguration)
        Try
          Dim MaxValue As Integer = Integer.MaxValue
          Conf.SetServiceOperationAccessRule("*", ServiceOperationRights.All)
          Conf.SetEntitySetAccessRule("*", EntitySetRights.All)
          Conf.UseVerboseErrors = True
          Conf.MaxBatchCount = MaxValue
          Conf.MaxChangesetCount = MaxValue
          Conf.MaxExpandCount = MaxValue
          Conf.MaxExpandDepth = MaxValue
          Conf.MaxObjectCountOnInsert = MaxValue
          Conf.MaxResultsPerCollection = MaxValue
        Catch ex As Exception

        End Try
      End Sub

     

     

     

    In the host (Console Application for testing):

    Code Snippet

    EntityDataServiceHost = New DataServiceHost(GetType(BusinessEntityDataService), ur)
    EntityDataServiceHost.Open()

    Dim MaxValue As Integer = Integer.MaxValue
    Dim MyEndpoint = EntityDataServiceHost.Description.Endpoints.Find(FoundUri)
    Dim MyElements = MyEndpoint.Binding.CreateBindingElements()
    With MyElements.Find(Of ServiceModel.Channels.WebMessageEncodingBindingElement)()
      .MaxReadPoolSize = MaxValue
      .MaxWritePoolSize = MaxValue
      .ReaderQuotas.MaxArrayLength = System.Xml.XmlDictionaryReaderQuotas.Max.MaxArrayLength
      .ReaderQuotas.MaxBytesPerRead = System.Xml.XmlDictionaryReaderQuotas.Max.MaxBytesPerRead
      .ReaderQuotas.MaxDepth = System.Xml.XmlDictionaryReaderQuotas.Max.MaxDepth
      .ReaderQuotas.MaxNameTableCharCount = System.Xml.XmlDictionaryReaderQuotas.Max.MaxNameTableCharCount
      .ReaderQuotas.MaxStringContentLength = System.Xml.XmlDictionaryReaderQuotas.Max.MaxStringContentLength
    End With
    With MyElements.Find(Of ServiceModel.Channels.TransportBindingElement)()
      .MaxReceivedMessageSize = MaxValue
      .MaxBufferPoolSize = MaxValue
    End With
    MyEndpoint.Binding = New ServiceModel.Channels.CustomBinding(MyElements)

     


    When I run the host and check its properties I find the following.
    EntityDataServiceHost.ChannelDispatchers.First.Listener turns out to be a HttpChannelListener, and it's the only one left I can see that has its MaxBufferSize and MaxReceivedMessageSize set to 64K.
    But there's no way I can change this value:
    The HttpChannelListener class from the .Net Framework is not accessible to programmers and even though you try to use late binding to access the properties MaxBufferSize and MaxReceivedMessageSize, they appear to be read-only.

     

    Is this Listener the cause of the problem or am I just missing something?

    Thursday, November 13, 2008 8:56 AM

All replies

  • I think its the 64k limitation. Here's another thread in the forum which tells how to configure this: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3894286&SiteID=1

     

    Thanks

    Pratik

    Friday, November 14, 2008 1:21 AM
    Moderator
  • Hi Pratik,

     

    Thank you for your quick reply.

    I've seen that topic as some other topics regarding this problem, but I got the impression none of them were actually answered to the full.

    I've searched internet as well, but couldn't get more information than I got over here.

     

    The topic you mention and its provided suggestions were taken into consideration and implemented as far as possible (see the Transport Quotas in my code snippets). Unfortunately, to no avail.

    When I use QuickWatch to verify the Max... properties of the host and bindings, I see that they're maxed.

    Except for the MaxBufferSize and MaxReceivedMessageSize properties (set to 64K) of the HttpChannelListener, which is unaccessible to coders.

     

    Is this is a strict limitation to the sending quotum in ADO.NET Data Services?

    If so, we have a serious problem, because a single Entity in our model could easily contain more than 64K of data.

     

    Please advise...

    Friday, November 14, 2008 11:55 AM
  •  

    Hi ,

     Can you please provide the complete stack trace for the error message returned from the server when you try to POST a payload greater than 64 K ?

    You can turn on Dev Error Mode Debugging following the instructions here :

    Debugging Ado.net Data Services

     

    A fiddler trace would also help .

    Tuesday, November 25, 2008 12:28 AM
    Moderator
  • <System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults:=True)> _

     

    and

     

    Conf.UseVerboseErrors = True

     

    were already present in the code for the data service.

     

     

    Please find the information that I get returned in my client and from Fiddler below.

     

    = Client app =

     

    ex.StackTrace:
    An error occurred while processing this request.
       at System.Data.Services.Client.DataServiceContext.SaveAsyncResult.HandleBatchResponse()
       at System.Data.Services.Client.DataServiceContext.SaveAsyncResult.EndRequest()
       at System.Data.Services.Client.DataServiceContext.SaveChanges(SaveChangesOptions options)
       at ClientSDK.Client.Insert() in D:\Visual Basic\2008\Solutions\ClientSDK\Client.vb:line 374

     

    DirectCast(ex.InnerException,System.Exception).StackTrace:
    BadRequest
       at System.Data.Services.Client.DataServiceContext.SaveAsyncResult.<HandleBatchResponse>d__1d.MoveNext()

     

    = Fiddler =

     

    Statistics:
    Request Count:  1
    Bytes Sent:  66.983
    Bytes Received: 113

     

    ACTUAL PERFORMANCE
    --------------
    Requests started at: 12:56:49:5780
    Responses completed at: 12:56:50:1250
    Total Sequence time: 00:00:00.5470000

     

    RESPONSE CODES
    --------------
    HTTP/400:  1

    RESPONSE BYTES (by Content-Type)
    --------------
    ~headers: 113

     

    Request:
    POST /BusinessEntityDataService.svc/Values HTTP/1.1
    User-Agent: Microsoft ADO.NET Data Services
    Accept: application/atom+xml,application/xml
    Accept-Charset: UTF-8
    DataServiceVersion: 1.0;NetFx
    MaxDataServiceVersion: 1.0;NetFx
    Content-Type: application/atom+xml
    Host: ndshbs:21000
    Content-Length: 66595
    Expect: 100-continue
    Connection: Keep-Alive

    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <entry xmlnsBig Smile="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
      <category scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" term="EntityModel.Value" />
      <title />
      <updated>2008-11-25T11:56:49.556Z</updated>
      <author>
        <name />
      </author>
      <id />
      <content type="application/xml">
        <mStick out tongueroperties>
          <d:BinaryValue m:type="Edm.Binary" m:null="true" />
          <d:CreatedAt m:type="Edm.DateTime" m:null="true" />
          <d:FileStreamValue m:type="Edm.Binary" m:null="true" />
          <d:ModifiedAt m:type="Edm.DateTime" m:null="true" />
          <d:TextValue>

     

    -- A lot of text containing up to 64K of data --

     

    </d:TextValue>
          <d:ValueDescription>Value @ 25-11-2008 12:56:49</d:ValueDescription>
          <d:ValueID m:type="Edm.Guid">5c9db2ae-7d1a-46e8-8e4f-2c6dd3728c05</d:ValueID>
          <d:ValueName>Value @ 25-11-2008 12:56:49</d:ValueName>
        </mStick out tongueroperties>
      </content>
    </entry>

     

     

    Response:
    HTTP/1.1 400 Bad Request
    Content-Length: 0
    Server: Microsoft-HTTPAPI/2.0
    Date: Tue, 25 Nov 2008 11:56:50 GMT


     

    Tuesday, November 25, 2008 12:19 PM
  • It took a long time to figure this out but you need this:

    We config needs 

    <httpRuntime maxRequestLength="500000"/>

    and your service needs this

       <system.serviceModel> 
          <services> 
             <service behaviorConfiguration="Blob.DataService.Service1Behavior" name="Blob.DataService.BlobWebDataService">  
                <endpoint address="" binding="webHttpBinding" name="MyBinding" contract="System.Data.Services.IRequestHandler" bindingConfiguration="RestBindingConfiguration" /> 
                <endpoint address="MyMex" binding="mexHttpBinding" contract="IMetadataExchange"/>  
             </service> 
             <service behaviorConfiguration="Atrion.Blob.DataService.Service1Behavior" name="Atrion.Blob.DataService.Service1">  
                <endpoint address="" binding="wsHttpBinding" contract="Blob.DataService.IService1">  
                   <identity> 
                      <dns value="localhost" /> 
                   </identity> 
                </endpoint> 
                <endpoint address="mex2" binding="mexHttpBinding" contract="IMetadataExchange" /> 
             </service> 
          </services> 
          <bindings> 
             <webHttpBinding> 
                <binding  name="RestBindingConfiguration" maxBufferSize="15000000" maxReceivedMessageSize="15000000">  
                   <readerQuotas maxStringContentLength="5000000" maxArrayLength="5000000" maxBytesPerRead="5000000" /> 
                   <security mode="None" /> 
                     
                </binding> 
                <!--<binding name="higerMessageSize" maxBufferSize="5000000" maxReceivedMessageSize="122880">  
              <readerQuotas maxStringContentLength="5000000" maxArrayLength="5000000" maxBytesPerRead="5000000" /> 
              <security mode="None" /> 
            </binding>--> 
             </webHttpBinding> 
          </bindings> 
          <behaviors> 
             <serviceBehaviors> 
                <behavior name="Blob.DataService.Service1Behavior">  
                   <!-- 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="false" />                 
                </behavior> 
             </serviceBehaviors> 
          </behaviors> 
          <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> 
       </system.serviceModel> 
    Thursday, December 18, 2008 1:58 AM
  • Can you try the instructions in this blog post ?
    Astoria & IIS , HTTP 400 Bad Request on Posting Large Payloads to an astoria service
    Phani Raj Astoria
    Thursday, December 18, 2008 6:59 PM
    Moderator
  • I had this issue too and could not figure it out for a while.  For me, this issue was naming.  The "service name" under services has to match exactly, including namespace the service name in your *.svc file.  If they don't match, you don't get an error, it just does not load your custom endpoint and binding configuration.  Once I found that, it works now with large messages.  They really need to address these config files better somehow.  These things are killing me every time I need to config something in wcf or other.

      <system.serviceModel>
        <diagnostics>
          <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
        </diagnostics>
        <services>
          <service name="ShiftWorkService.RestService"> <!-- Match name in *.svc file -->
            <endpoint address="http://localhost:7070/RestService.svc" binding="webHttpBinding" bindingConfiguration="higherMessageSize" contract="System.Data.Services.IRequestHandler" />
          </service>
        </services>
        <bindings>
          <webHttpBinding>
            <!-- configure the maxReceivedMessageSize  value to suit the max size of
             the request ( in bytes ) you want the service to recieve-->
            <binding name="higherMessageSize" maxReceivedMessageSize="1048576" />
          </webHttpBinding>
        </bindings>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
      </system.serviceModel>
    Friday, December 19, 2008 12:08 AM