An existing connection was forcibly closed by the remote host - WCF Data Service error

Paul Aldred-Bann picture Paul Aldred-Bann · Jan 21, 2013 · Viewed 20.2k times · Source

I'm currently using WCF Data Services (well, ADO.Net Data Services) with Entity Framework and am getting the following error when performing a POST (omitted / changed some irrelevant info):

<?xml version="1.0" encoding="utf-8"?><m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><m:code /><m:message xml:lang="en-GB">The URI 'http://localhost:56568/MyWcfDataServices.svc/EntitySetName(pk_id)' is not valid for POST operation. For POST operations, the URI must refer to a service operation or an entity set.</m:message></m:error>

Having a look around online, I can't seem to find much information about this message so debugging it is a little difficult. It's likely happening because one of the attributes I'm posting is a large base64 string (it works fine if I don't post this). I've tried setting the maxRequestLength to the following:

<httpRuntime maxRequestLength="102400" />

But it doesn't seem to have helped. While I'll continue working through this, I thought I'd make a quick post on here to see if anyone knows something that may help.

My WCF Data Service class looks like this:

public class MyWcfDataServices: DataService<ContextName>
{
    public static void InitializeService(DataServiceConfiguration config)
    {
        // set entity access rules etc
    }
}

Thanks

EDIT: I don't seem to be getting anywhere with this. Here's what I've tried so far.

On the server side I've set the following bindings:

<system.serviceModel>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" 
                             minFreeMemoryPercentageToActivateService="0" />
  <services>
    <service name="MyWcfDataServices" 
             behaviorConfiguration="myBehaviorConfig">
      <endpoint address=""
                binding="webHttpBinding"
                bindingConfiguration=""
                contract="System.Data.Services.IRequestHandler" />
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="myBehaviorConfig">
        <serviceMetadata httpGetEnabled="true"/>
        <serviceDebug includeExceptionDetailInFaults="true"/>
        <dataContractSerializer maxItemsInObjectGraph="2147483647" />
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>

Hoping that the maxItemsInObjectGraph attribute would be the solution. Do these bindings look correct? Am I missing some attribute that will let me POST more data to the server? Do I need to configure this service behavior on the client as well?

Answer

Paul Aldred-Bann picture Paul Aldred-Bann · Jan 21, 2013

OK, here's what I did to fix the problem. First I enabled tracing on the server by adding the following to my web.config:

<system.diagnostics>
  <sources>
    <source name="System.ServiceModel"
            switchValue="Information, ActivityTracing"
            propagateActivity="true">
      <listeners>
        <add name="traceListener"
            type="System.Diagnostics.XmlWriterTraceListener"
            initializeData="c:\logs\Traces.svclog"  />
      </listeners>
    </source>
  </sources>
</system.diagnostics>

This gave me a lot more information about the issues, specifically in my case the max request length was still 65536, which indicated my bindings weren't being picked up. This was down to two things, first the name part of my service configuration wasn't correct - it needed to include the namespace information. I ended up with this (I had to put this in the client's web.config too):

<services>
  <service name="Solution.Project.MyWcfDataServices">
    <endpoint address=""
              binding="webHttpBinding"
              bindingConfiguration="webHttpConfig"
              contract="System.Data.Services.IRequestHandler" />
  </service>
</services>
<bindings>
  <webHttpBinding>
    <binding name="webHttpConfig" 
              allowCookies="true"
              maxReceivedMessageSize="20000000"
              maxBufferSize="20000000"
              maxBufferPoolSize="20000000">
      <readerQuotas maxDepth="32"
                    maxArrayLength="200000000"
                    maxStringContentLength="200000000" />
    </binding>
  </webHttpBinding>
</bindings>

Finally, I had to change factory in the markup of my .svc file from the template generated System.Data.Services assembly to Microsoft's ODATA assembly (which contains System.Data.Services namespaces too) System.Data.Services.DataServiceHostFactory, Microsoft.Data.Services, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.

I've less hair now than when I started, but that's the price you pay I suppose.