2

I have a WCF service and in this service I return a class with lots of properties, some of which are classes themselves and it is a little complex but not hugely. I've done a similar thing on the same project with another WCF service and it all worked fine. But this one gave me this error when I used it.

[System.ServiceModel.CommunicationException]    {"An error occurred while receiving the HTTP response to http://xxx/Service.svc. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details."}  System.ServiceModel.CommunicationException

The inner exception is

[System.Net.WebException]   {"The underlying connection was closed: An unexpected error occurred on a receive."}    System.Net.WebException

The inner exception of that says

[System.IO.IOException] {"Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."}   System.IO.IOException

The inner exception of that says

[System.Net.Sockets.SocketException]    {"An existing connection was forcibly closed by the remote host"}   System.Net.Sockets.SocketException

So, here's what I've tried. I thought that maybe there is some error in my .svc file or perhaps there is some error in my configuration of the .config files, but as far as I can see there isn't. Then, I thought I should try and see if I can send a simple type from the server to the client. I therefore created a method called GetInt() which returns 7. I called this on the client and it worked fine. Therefore, I think it is the data that I'm sending back from the server that is not supported. I can't see why, because as I've said I've sent complex types before on the same project (just yesterday) and it all worked. Anyway, here is my class that I am sending. Perhaps, someone can point out what might not be supported. Or perhaps someone knows what else might have caused this.

    public class Hotels
    {
        public string Language { get; set; }
        public string Datum { get; set; }
        public  List<HotelListing> HotelListing { get; set; }
    }

    public class HotelListing
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public string Country { get; set; }
        public decimal Latitude { get; set; }
        public decimal Longitude { get; set; }
        public string Category { get; set; }
        public List<PhoneNumber> PhoneNumbers { get; set; }
        public Address Address { get; set; }
        public Content Content { get; set; }
    }

    public class Content
    {
        public Description Description { get; set; }
        public List<Review> Reviews { get; set; }
        public Image Image { get; set; }
        public AtrttributeData AtrttributeData { get; set; }
    }

    public class AtrttributeData
    {
        public string Link { get; set; }
        public string Title { get; set; }
        public NameValueCollection Attributes { get; set; }
    }

    public class Image
    {
        public string Type { get; set; }
        public string ImageURL { get; set; }
        public string HotelURL { get; set; }
    }

    public class Review
    {
        public string Type { get; set; }
        public string Link { get; set; }
        public string Author { get; set; }
        public string Body { get; set; }
        public NameValueCollection Ratings { get; set; } 
    }

    public class Description
    {
        public string Link { get; set; }
        public string Title { get; set; }
        public string Body { get; set; }
    }

    public class Address
    {
        public string Format { get; set; }
        public string Addr1 { get; set; }
        public string Addr2 { get; set; }
        public string City { get; set; }
        public string PostCode { get; set; }
    }

    public class PhoneNumber
    {
        public string Type { get; set; }
        public string Number { get; set; }
    }

The method in question is this

[OperationContract]
Hotels GetHotels();

Any help would be greatly appreciated.

Here is my configuration section

<binding name="BasicHttpBinding_ITablet" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="None">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>

<snip>

<endpoint address="http://xxx/Service.svc"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ITablet"
                contract="SupplierInterfaceTabletService.ITablet" name="BasicHttpBinding_ITablet" />

thanks,

Sachin

Sachin Kainth
  • 45,256
  • 81
  • 201
  • 304
  • 1
    Please add you system.serviceModel section from your application config file. It may be that you don't have the max message size set large engough, or another config setting related to message size. – user957902 Aug 08 '12 at 14:31
  • I would turn on tracing and see if you can get more diagnostic info. Configuring tracing is decribed [here](http://msdn.microsoft.com/en-us/library/ms733025.aspx). – user957902 Aug 08 '12 at 14:53
  • On the server or the client side? – Sachin Kainth Aug 08 '12 at 15:01

2 Answers2

1

Try return DataContract (not Class). This a DataContract with a list of another DataContract and an example of inheritance.

[DataContract]
public class sDoc
{
    [DataMember]
    public int sID;
    [DataMember]
    public int sParID;
    [DataMember]
    public List<sDocProp> Props;
    [DataMember]
    public string SessionID;

    public string NotDataMember;
}

[DataContract]
[KnownType(typeof(sDocPropStringSV))]
public class sDocProp
{
    [DataMember]
    public int ID;
    [DataMember]
    public string Name;
    [DataMember]
    public ArrivalStatus ArrivalStatus;
}

[DataContract]
public class sDocPropStringSV : sDocProp
{
    [DataMember]
    public string Value;
}
paparazzo
  • 44,497
  • 23
  • 105
  • 176
  • This is not true: the `DataContract` and `DataMember` attributes are optional. If not present, all public properties of the class will be serialized. – CodeCaster Aug 08 '12 at 14:33
  • Yes, I did not do this with my other example yesterday and it all worked fine. I have this sort of thing on my client side. – Sachin Kainth Aug 08 '12 at 14:41
  • @CodeCaster OK I changed it to try. – paparazzo Aug 08 '12 at 14:47
  • The question does not indicate the use of DataContracts. I would break it down and return something very simple and build from there. – paparazzo Aug 08 '12 at 14:59
0

I love .NET it's so rubbish sometimes. The problem was NameValueCollections. For some reason WCF had a problem with passing those from the server to the client. Go figure!

Sachin Kainth
  • 45,256
  • 81
  • 201
  • 304
  • It's not WCF - it's the NameValueCollection. It's not serializable out of the box. Check out this answer: [XML serialization of a collection in C#](http://stackoverflow.com/a/1465464/745969). – Tim Aug 08 '12 at 16:49