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

3

9

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?

Tarragona answered 21/1, 2013 at 10:0 Comment(0)
T
20

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.

Tarragona answered 21/1, 2013 at 14:56 Comment(1)
You deserve two upvotes, one for the answer, one for "less hair" joke. Alas, I can only upvote once.Maulstick
P
10

I was getting this problem because some of the DataMembers in my DataContract had only get method. For example

[DataMember]
public Name { get; } 

will cause this error. To fix the problem you should have

[DataMember]
public Name {get; set;}
Pheidippides answered 6/12, 2016 at 10:50 Comment(2)
You saved my day, thanks, i had to get rid of set because of exception free xml parsed value is set by me, so no need to have set, but empty set block also works e.g. set {}Interstate
Unbelievable... this was my problem as well... I hate WCF!Friary
T
2

Another cause of this error is trying to declare an IReadOnlyDictionary as a DataMember.

[DataMember]
public IReadOnlyDictionary<String, Object> Foo { get; set; }

The fix is pretty easy: just use IDictionary instead.

[DataMember]
public IDictionary<String, Object> Foo { get; set; }

I assume this also applies to the other implementations of IReadOnlyCollection such as IReadOnlyList.

Transmissible answered 19/6, 2018 at 15:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.