2
votes

So I'm self hosting a WCF service. When I call my GetProject() method via the client I get a Unhandled CommuncationException with an InnerException of

"The underlying connection was closed: An unexpected error occurred on a receive."

And the InnerException of that:

"Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."

Now I know this is just a generic message that doesn't tell me much. So I configured a Service Trace and this is what I got:

at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.Reply(MessageRpc& rpc)System.Runtime.Serialization.SerializationException: Type 'System.FormatException' with data contract name 'FormatException:http://schemas.datacontract.org/2004/07/System' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

So I took this message and modified my code and I believe now that I am doing this correctly. I have followed several tutorials, but I still keep getting this exception in the Service Trace.

In my ServiceContract I have the following:

[OperationContract]
Project GetProject(int id);

Edit Removed KnownTypeAttribute use. Commented out here to reflect the changes.

Here is my implementation of the Project class and the classes that it utilizes:

    [DataContract]
    //[KnownType(typeof(Contact))]
    //[KnownType(typeof(ProjectDetails))]
    //[KnownType(typeof(CommercialEntity))]
    public class Project
    {
        [DataMember]
        public ProjectDetails details = new ProjectDetails();
        [DataMember]
        public List<Contact> contacts = new List<Contact>();
        [DataMember]
        public List<CommercialEntity> POs = new List<CommercialEntity>();
        [DataMember]
        public List<CommercialEntity> invoices = new List<CommercialEntity>();
        [DataMember]
        public List<CommercialEntity> quotes = new List<CommercialEntity>();
        [DataMember]
        public List<CommercialEntity> CRs = new List<CommercialEntity>();
    }

    [DataContract]
    public class ProjectDetails 
    {
        [DataMember]
        public int projectId { get; set; }
        [DataMember]
        public string name { get; set; }
        [DataMember]
        public int calYearId { get; set; }
        [DataMember]
        public string projectState { get; set; }
        [DataMember]
        public string reportTitle { get; set; }
        [DataMember]
        public int plantId { get; set; }
        [DataMember]
        public string holdNumber { get; set; }
        [DataMember]
        public string holdDescription { get; set; }
        [DataMember]
        public string remarks { get; set; }
        [DataMember]
        public string adminComments {get; set; }
        [DataMember]
        public int companyId { get; set; }
        [DataMember]
        public int customerId { get; set; }
        [DataMember]
        public string folderNumber { get;  set; }
        [DataMember]
        public int invoicedInFull { get; set; }
        [DataMember]
        public int approved { get; set; }
        }
    }

    [DataContract]
    public class CommercialEntity
    {
        [DataMember]
        public string number { get; set; }
        [DataMember]
        public DateTime date { get; set; }
        [DataMember]
        public string comments { get; set; }

        public CommercialEntity(string setNumber, DateTime setDate, string setComments)
        {
            number = setNumber;
            date = setDate;
            comments = setComments;
        }
    }

    [DataContract]
    public class Contact
    {
        [DataMember]
        public string firstName { get; set; }
        [DataMember]
        public string lastName { get; set; }
        [DataMember]
        public string emailAddress { get; set; }
        [DataMember]
        public string phoneNumber { get; set; }
        [DataMember]
        public int alert { get; set; }
        [DataMember]
        public int projectLead { get; set; }
        [DataMember]
        public int mainContact { get; set; }

        public Contact(string first, string last, string email, string phone, int alrt, int projLead, int mainCntct)
        {
            firstName = first;
            lastName = last;
            emailAddress = email;
            phoneNumber = phone;
            alert = alrt;
            projectLead = projLead;
            mainContact = mainCntct;
        }

        public Contact() { }
    }

Where is the hole in my understanding?

Here is what I see when I run the client:

See the end of this message for details on invoking just-in-time (JIT) debugging instead of this dialog box.

***** Exception Text *******

System.ServiceModel.CommunicationException: An error occurred while receiving the HTTP response to myInternalIP:myPort/ProjectService/ProjectService. 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.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host

at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)

at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)

--- End of inner exception stack trace ---

at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)

at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size)

at System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead)

--- End of inner exception stack trace ---

at System.Net.HttpWebRequest.GetResponse()

at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

--- End of inner exception stack trace ---

Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)

at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)

at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)

at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)

at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)

at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]:

at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)

at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)

at IProjectService.GetQuerytoList(Int32 id)

at ProjectServiceClient.GetQuerytoList(Int32 id) in C:\Users\drwill\documents\visual studio 2010\Projects\ProjectBaseWCF\ProjectBase\generatedProxy.cs:line 1065
at ProjectWCFClient.MainForm.openToolStripMenuItem_Click(Object sender, EventArgs e) in C:\Users\drwill\documents\visual studio 2010\Projects\ProjectBaseWCF\ProjectBase\PBMain.cs:line 961

at ProjectWCFClient.MainForm.ProjectListBox_DoubleClick(Object sender, EventArgs e) in C:\Users\drwill\documents\visual studio 2010\Projects\ProjectBaseWCF\ProjectBase\PBMain.cs:line 55

at System.Windows.Forms.Control.OnDoubleClick(EventArgs e)

at System.Windows.Forms.ListBox.WndProc(Message& m)

at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)

at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)

at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Here is my Client config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IProjectService" maxReceivedMessageSize="500000000" />
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://192.168.0.99:9000/ProjectService/ProjectService"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IProjectService"
                contract="IProjectService" name="BasicHttpBinding_IProjectService" />
        </client>
    </system.serviceModel>
</configuration>

Here is my service config:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true"/>
  </system.web>
  <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="ProjectBaseWCFServiceLib.Service1Behavior" name="ProjectBaseWCFServiceLib.ProjectService">
        <endpoint address="" binding="basicHttpBinding" contract="ProjectBaseWCFServiceLib.IProjectService">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/Design_Time_Addresses/ProjectBaseWCFServiceLib/Service1/"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ProjectBaseWCFServiceLib.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 -->
          <dataContractSerializer maxItemsInObjectGraph="2147483646"/>
          <serviceDebug includeExceptionDetailInFaults="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

In addition, I programatically configure my Console App Host with:

     BasicHttpBinding binding = new BasicHttpBinding();
     binding.OpenTimeout = new TimeSpan(0, 10, 0);
     binding.CloseTimeout = new TimeSpan(0, 10, 0);
     binding.SendTimeout = new TimeSpan(0, 10, 0);
     binding.ReceiveTimeout = new TimeSpan(0, 10, 0);
     binding.MaxReceivedMessageSize = 500000000;
     binding.MaxBufferSize = 500000000;
     binding.MaxBufferPoolSize = 500000000;

     selfHost.AddServiceEndpoint(typeof(IProjectService), binding, "ProjectService");
3
Side note: those new() statements and constructors may not be working the way you're expecting.Dave Ziegler
Is Proxy client and server running on same machine?YK1
No, the server is running on a different machine than the client.Derek W
Same issue with KnownType removed?Dave Ziegler

3 Answers

3
votes

Okay. So this is a bit late, but here is what it was:

The System.FormatException that was being thrown was due to the occurrence of an int.Parse("0") inside the GetProject(int id) method when I was calling it.

So I altered the method to handle the "0" case by calling the much more robust Convert.ToInt32("0").

I think the lesson learned here is that you should first make sure that the method you are executing works. Then and only then should you start asking if the DataContractSerializer is not adequate to serialize your types.

0
votes

Try to add a parameterless constructor for CommercialEntity

0
votes

I dont think you need KnownType - It could be possible parsing error with DateTime. Check culture on client and server machines.

EDIT: From further information provided, it looks like your proxy is incorrectly configured - compared to the binding configurations on the server. Re-create the proxy using Add Service Reference or SvcUtil.exe