"无法从传输连接读取数据:远程主机强行关闭现有连接

Mor*_*rat 8 wcf

我使用Visual Studio 2010和MS SQL Server 2005.我是WCF的新手,我正在尝试学习开发一个小任务管理应用程序.

目前我有一个带有两个控制台应用程序的解决方案--WCF服务 - 连接到WCF服务的客户端以测试我的代码

WCF服务使用LINQ to SQL连接到数据库.我已经实现了一个OperationContract,它将一些内容插入到WCF服务后面的数据库中并且它可以工作.我已经实现了一个OperationContract,它将WCF服务中的GUID返回给客户端,并且也可以.

当我尝试从WCF服务检索List列表时,它失败并出现以下错误:

  • "收到对localhost:8000/TaskerTest/Service/operations的HTTP响应时发生错误.这可能是由于服务端点绑定不使用HTTP协议.这也可能是由于服务器中止了HTTP请求上下文

  • InnerException:基础连接已关闭:接收上发生意外错误.

我的合同(前两个工作.GetLists是问题):

[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();
}
Run Code Online (Sandbox Code Playgroud)

实施:

    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;
    }
Run Code Online (Sandbox Code Playgroud)

数据库访问代码:

     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;

    }
Run Code Online (Sandbox Code Playgroud)

并且客户端代码(WCF服务作为服务引用添加到客户端项目中):

        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();
Run Code Online (Sandbox Code Playgroud)

客户端因以上异常而失败:client.GetLists();

我可以根据读者的需要提供任何其他详细信息.

UPDATE

我已经开始追踪了

  <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>
Run Code Online (Sandbox Code Playgroud)

然后我在生成的日志上运行Microsoft Service Trace Viewer并收到以下错误:

尝试序列化参数时出错.InnerException消息是"Type"System.DelegateSerializationHolder + DelegateEntry',数据协定名称为"DelegateSerializationHolder.DelegateEntry:http://schemas.datacontract.org/2004/07/System"

我现在已经将[DataContract]添加到我的dbml文件中的"ToDoList"类中​​,现在我没有收到异常.我在客户端获得了正确的结果数量但是每个类的内容似乎都是空的.

Mor*_*rat 2

我的数据库类是使用 dbml 文件 (LINQ to SQL) 自动生成的。

在我向“TaskerModel.designer.cs”(自动生成的文件)中的 ToDoList 类添加 [DataContract()] 属性后,我不再收到异常,但我在客户端检索到的类只有默认值对于每个成员。

然后我将 [DataMember()] 属性添加到 ToDoList 类的所有成员并添加

[ServiceKnownType(typeof(ToDoList))]
Run Code Online (Sandbox Code Playgroud)

    [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();
}
Run Code Online (Sandbox Code Playgroud)

现在它起作用了。不知道是否有更简单的方法,但现在可以了。如果有人知道更好的方法来做到这一点,我将不胜感激。