2012-05-27 16 views
8

Uso Visual Studio 2010 y MS SQL Server 2005. Soy nuevo en WCF y estoy tratando de aprender mientras desarrollo un . tarea pequeña aplicación de gestión"No se pudieron leer los datos de la conexión de transporte: una conexión existente fue cerrada a la fuerza por el host remoto

Por el momento tengo una solución con dos aplicaciones de consola en su interior - el servicio WCF - un cliente que se conecta al servicio WCF para probar mi código

el servicio WCF se conecta a a db utilizando LINQ to SQL. Implementé OperationContract que inserta algo en el archivo db detrás del servicio WCF y funciona. Implementé OperationContract que devuelve un GUID del servicio WCF al cliente y eso también funciona.

Cuando intento para recuperar una lista de lista en el servicio WCF se produce un error con el siguiente error:

  • "Se ha producido un error al recibir la respuesta HTTP a localhost: 8000/TaskerTest/servicios/operaciones Esto podría deberse a que el enlace del punto final del servicio no utiliza el protocolo HTTP. Esto también podría deberse a que el servidor abortó el contexto de solicitud HTTP

  • InnerException: se cerró la conexión subyacente: se produjo un error inesperado en un recibir.

Mis contratos (los primeros dos trabajos. GetLists es el problema):

La aplicación:

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; 
    } 

El código de acceso DB:

 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; 

    } 

Y el código de cliente (el servicio WCF se agrega como una referencia de servicio a el proyecto del cliente):

 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(); 

El cliente falla con la excepción anterior en: client.GetLists();

Puedo proporcionar cualquier detalle adicional según lo necesiten los lectores.

ACTUALIZACIÓN

me he vuelto con el seguimiento en

<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> 

Entonces me he encontrado de seguimiento de servicio Microsoft Viewer en el registro generado y obtuvo el siguiente error:

No se un error al intentar serializar el parámetro. El mensaje InnerException era 'Tipo' System.DelegateSerializationHolder + DelegateEntry 'con el nombre del contrato de datos' DelegateSerializationHolder.DelegateEntry: http: //schemas.datacontract.org/2004/07/System 'no se espera

He añadido ahora [DataContract] a la clase "ToDoList" en mi archivo dbml y ahora no recibo una excepción. Obtengo el número correcto de resultados en mi cliente, PERO el contenido de cada clase parece estar vacío.

Respuesta

2

Mis clases de base de datos se autogeneraron utilizando un archivo dbml (LINQ to SQL).

Después de haber agregado un atributo [DataContract()] a la clase ToDoList en "TaskerModel.designer.cs" (el archivo generado automáticamente) ya no recibí una excepción, pero las clases que recuperé en el cliente solo tenía valores predeterminados para cada miembro.

Luego añade [DataMember()] atribuye a todos los miembros de la clase ToDoList y ha añadido

[ServiceKnownType(typeof(ToDoList))] 

a

[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(); 
} 

Y ahora funciona. No sé si hay una manera más fácil de hacerlo pero funciona ahora. Si alguien sabe de una mejor manera de hacer esto, agradecería un comentario.

0

Tuve el mismo error al llamar a mi servicio de descanso de WCF. El problema parecía ser causado por el tipo de datos que estaba devolviendo como respuesta.

Devolví JSON y mi objeto de respuesta tenía una variable con tipo de datos DateTime. Cuando reemplacé el DateTime con una cadena, el problema desapareció y se devolvió una respuesta adecuada. Probablemente ayudará a alguien que se meta en el mismo problema.

Reemplazar:

[DataMember] 
public DateTime dateFrom {get;set;} 

con este

[DataMember] 
public string dateFrom {get;set;} 
0

En mi caso, el problema era que no había una propiedad de sólo lectura. Agregue un conjunto vacío(); y resuelve mi problema

Cuestiones relacionadas