Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

wcf

I use Visual Studio 2010 and MS SQL Server 2005. I'm new to WCF and I'm trying to learn while developing a small task managing application.

At the moment I have a solution with two console applications inside it - the WCF service - a client connecting to the WCF service to test out my code

The WCF service connects to a db using LINQ to SQL. I've implemented an OperationContract which inserts something into the db behind the WCF service and it works. I've implemented an OperationContract which returns a GUID from the WCF service to the client and that works too.

When I try to retrieve a list of List from the WCF service it fails with the following error:

  • "An error occurred while receiving the HTTP response to localhost:8000/TaskerTest/Service/operations. 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

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

My Contracts (the first two work. GetLists is the problem):

[ServiceContract(Namespace = "http://Tasker_Server")]
public interface IOperations {
    [OperationContract]
    string CreateList(string listName, string text);
    [OperationContract]
    string UpdateList(int idList, string listName, string text);
    [OperationContract]
    List<ToDoList> GetLists();
}

The implementation:

    public List<ToDoList> GetLists() {
        Guid token = OperationContext.Current.IncomingMessageHeaders.GetHeader<Guid>("token", "ns");
        int? userID = CheckCache(token);

        if (userID != null) {
            List<ToDoList> lst = DBAccess.GetListsByUserId(userID.Value);
            return lst;
        }
        else
            return null;
    }

The DB access code:

     public static List<ToDoList> GetListsByUserId(int idCredential) {
        TaskerModelDataContext tmdc = new TaskerModelDataContext();
        List<ToDoList> lists = tmdc.ToDoLists.Where(entry => entry.id_Credential == idCredential).ToList<ToDoList>();
        return lists;

    }

And the client code (the WCF service is added as a Service Reference to the client project):

        TaskerService.LoginClient test2 = new LoginClient();
        string username = "usr1", password = "psw1";
        test2.ClientCredentials.UserName.UserName = username;
        test2.ClientCredentials.UserName.Password = password;

        Guid result = Guid.Empty;
        try {
            result = test2.CheckCredentials(username, password);
            Console.WriteLine("Login OK!");
        }
        catch (Exception e) {
            Console.WriteLine(e.Message);
        }

        TaskerService.OperationsClient client = new OperationsClient();
        using(OperationContextScope contextScope = new OperationContextScope(client.InnerChannel)) {

            Guid testToken = result; Console.WriteLine(testToken.ToString());
            MessageHeader<Guid> mhg = new MessageHeader<Guid>(testToken);
            MessageHeader untyped = mhg.GetUntypedHeader("token", "ns");
            OperationContext.Current.OutgoingMessageHeaders.Add(untyped);

            client.GetLists();
        }
        client.Close();

The client fails with the above exception on: client.GetLists();

I can provide any additional details as needed by readers.

UPDATE

I've turned tracing on with

  <system.diagnostics>
    <trace autoflush="true" />
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="sdt"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData= "SdrConfigExample.e2e" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

Then I've run Microsoft Service Trace Viewer on the generated log and got the following error:

There was an error while trying to serialize parameter . The InnerException message was 'Type 'System.DelegateSerializationHolder+DelegateEntry' with data contract name 'DelegateSerializationHolder.DelegateEntry:http://schemas.datacontract.org/2004/07/System' is not expected

I've now added [DataContract] to the "ToDoList" class in my dbml file and now I don't receive an exception. I get the correct number of results in my client BUT the contents of each class seem to be empty.

like image 982
Morat Avatar asked May 27 '12 11:05

Morat


1 Answers

My database classes were auto-generated using a dbml file (LINQ to SQL).

After I've added a [DataContract()] attribute to the ToDoList class in "TaskerModel.designer.cs" (the auto generated file) I didn't receive an exception anymore but the classes I retrieved on the client only had default values for each member.

I then added [DataMember()] attributes to all the members of ToDoList class AND added

[ServiceKnownType(typeof(ToDoList))]

to

    [ServiceContract(Namespace = "http://Tasker_Server")]
    public interface IOperations {
        [OperationContract]
        string CreateList(string listName, string text);
        [OperationContract]
        string UpdateList(int idList, string listName, string text);
        [OperationContract]
        List<ToDoList> GetLists();
}

And now it works. Don't know if there's an easier way to do it but it works now. If anybody knows of a better way to do this I would appreciate a comment.

like image 171
Morat Avatar answered Oct 15 '22 09:10

Morat