2008-10-24 16 views
12

Tengo tres proyectos. Uno es un Proyecto de Servicios de WCF, uno es un Proyecto de WPF, y uno es un Proyecto de Prueba de Unidad de Microsoft. I fijó el proyecto de servicios WCF con un objeto de datos que tiene este aspecto:Excepción común de WCF: conexión inesperadamente cerrada

[DataContract] 
public enum Priority 
{ 
    Low, 
    Medium, 
    High 
} 

[DataContract] 
public struct TimeInfo 
{ 
    [DataMember] 
    public Int16 EstimatedHours { get; set; } 

    [DataMember] 
    public Int16 ActualHours { get; set; } 

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

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

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

[DataContract] 
public class Task 
{ 
    [DataMember] 
    public string Title { get; set; } 

    [DataMember] 
    public string Description { get; set; } 

    [DataMember] 
    public Priority Priority { get; set; } 

    [DataMember] 
    public TimeInfo TimeInformation { get; set; } 

    [DataMember] 
    public Decimal Cost { get; set; } 
} 

Mi contrato es el siguiente:

[ServiceContract] 
public interface ITaskManagement 
{ 
    [OperationContract] 
    List<Task> GetTasks(); 

    [OperationContract] 
    void CreateTask(Task taskToCreate); 

    [OperationContract] 
    void UpdateTask(Task taskToCreate); 

    [OperationContract] 
    void DeleteTask(Task taskToDelete); 
} 

Cuando trato de utilizar el servicio, ya sea en la aplicación de WPF o la Unidad Proyecto de prueba con este código:

var client = new TaskManagementClient(); 

textBox1.Text = client.GetTasks().ToString(); 

client.Close(); 

me sale el siguiente error: "la conexión subyacente se cerró: la conexión se cerró inesperadamente."

El app.config para la Unidad de WPF y Proyectos de Prueba este aspecto:

<system.serviceModel> 
    <bindings> 
     <wsHttpBinding> 
      <binding name="WSHttpBinding_ITaskManagement" closeTimeout="00:01:00" 
       openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
       bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" 
       maxBufferPoolSize="524288" maxReceivedMessageSize="65536" 
       messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" 
       allowCookies="false"> 
       <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
        maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
       <reliableSession ordered="true" inactivityTimeout="00:10:00" 
        enabled="false" /> 
       <security mode="Message"> 
        <transport clientCredentialType="Windows" proxyCredentialType="None" 
         realm="" /> 
        <message clientCredentialType="Windows" negotiateServiceCredential="true" 
         algorithmSuite="Default" establishSecurityContext="true" /> 
       </security> 
      </binding> 
     </wsHttpBinding> 
    </bindings> 
    <client> 
     <endpoint address="http://localhost:9999/TaskManagement.svc" 
      binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ITaskManagement" 
      contract="TaskManagement.ITaskManagement" name="WSHttpBinding_ITaskManagement"> 
      <identity> 
       <dns value="localhost" /> 
      </identity> 
     </endpoint> 
    </client> 
</system.serviceModel> 

y el web.config del servicio WCF tiene el siguiente aspecto:

<system.serviceModel> 
    <behaviors> 
     <serviceBehaviors> 
      <behavior name="InternetBasedWcfServices.TaskManagementBehavior"> 
       <serviceMetadata httpGetEnabled="true" /> 
       <serviceDebug includeExceptionDetailInFaults="false" /> 
      </behavior> 
      <behavior name="InternetBasedWcfServices.ScheduleManagementBehavior"> 
       <serviceMetadata httpGetEnabled="true" /> 
       <serviceDebug includeExceptionDetailInFaults="false" /> 
      </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <services> 
     <service behaviorConfiguration="InternetBasedWcfServices.TaskManagementBehavior" 
      name="InternetBasedWcfServices.TaskManagement"> 
      <endpoint address="" binding="wsHttpBinding" contract="InternetBasedWcfServices.ITaskManagement"> 
       <identity> 
        <dns value="localhost" /> 
       </identity> 
      </endpoint> 
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     </service> 
     <service behaviorConfiguration="InternetBasedWcfServices.ScheduleManagementBehavior" 
      name="InternetBasedWcfServices.ScheduleManagement"> 
      <endpoint address="" binding="wsHttpBinding" contract="InternetBasedWcfServices.IScheduleManagement"> 
       <identity> 
        <dns value="localhost" /> 
       </identity> 
      </endpoint> 
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     </service> 
    </services> 
</system.serviceModel> 

Este no es el primera vez que esto sucedió, y supongo que es un problema de configuración. Pero cada vez solía volar mi servicio y devolverlo o crear un nuevo proyecto de servicio. Entonces todo funciona maravillosamente. Si alguien tiene alguna idea, sería increíble. Gracias.

**

Updated: I've added comments for more of my troubleshooting on this problem. When an answer is available, if the answer is unpublished, I'll add it as an official "answer".

**

Respuesta

20

encontré la respuesta

Ok, no estoy seguro si es kewl responder a mi propia pregunta, pero aquí vamos. Por alguna razón la enumeración sea necesario para estar marcado con los atributos [EnumMember] como a continuación:

[DataContract] 
public enum Priority 
{ 
    [EnumMember] 
    Low, 
    [EnumMember] 
    Medium, 
    [EnumMember] 
    High 
} 

Una vez que hice que mis pruebas y servicios podrían ser llamados sin que se produzca el error. Todavía no estoy seguro de por qué se mostró ese error específico. El error no parece alinearse en ninguna correlación con la razón funcional por la que se produjo el error, pero esta solución definitivamente suavizó todo.

+2

De todas las excepciones aleatorias que alguien podría lanzar, ¿esta es la MEJOR que el equipo de WCF podría proponer? Se metió en el mismo problema, y ​​pasé una eternidad tratando de descubrirlo, y para hacerlo aún más irritante funcionó en mi máquina de prueba, pero no funcionaría correctamente cuando se moviera al servidor. IIS es malvado. – thaBadDawg

+0

responder su propia pregunta es todo bien: http://meta.stackexchange.com/questions/17463/can-i-answer-my-own-questions-even-those-where-i-knew-the-answer-fore -pregunto- ¡creo que debería haber una insignia para eso! :) – russau

+0

Pensé que esta respuesta era un poco aleatoria. ¡Pero solucionó totalmente mi caso! –

1

Podría estar lejos, pero podría ser una cosa seguridad ... He conseguido que el error antes, y lo resolvió ... pero estuve despierto durante días tratando de resolver muchos errores diferentes.

Tengo un artículo de la muestra haciendo algo básico, pero estoy usando net.tcp (con seguridad establecido en "None") aquí: Duplex WCF Services Hosted in IIS Using Net.Tcp

Además, cuando estás recibiendo el error es que ... en la línea ".Close()", o en la línea ".GetTasks(). ToString()"?

Otra cosa que puede comprobar es simplemente telnet a localhost en el puerto 9999 para ver si el servicio está escuchando por completo las conexiones entrantes.

3

Asegúrese de que nada que no sea una FaultException sea lanzado y devuelto al cliente.

7

Como usted mismo señaló, si marca la enumeración como DataContract, también tendrá que marcar los elementos.

Como alternativa, se puede simplemente eliminar el [DataContract] antes de que su enumeración como esto:

public enum Priority 
{  
    Low,  
    Medium,  
    High 
} 

Esto quiere trabajar, también, porque en este caso WCF se encarga de la enumeración por sí mismo. Si lo marcas como [DataContract], debes marcar cada elemento como te has fijado.

1

A veces, este error puede ser muy engañoso. Excepción común de WCF: la conexión inesperadamente cerrada puede ocurrir cuando la cultura no está configurada correctamente o en formato de cadena también.

Siguiendo falla:

new DateTime(adate.Year, adate.Month, firstday).ToString("d", cultureInfo); 

mientras que esto funciona:

CultureInfo culture = new CultureInfo(this.aculture.Name);    
Convert.ToString(new DateTime(adate.Year, adate.Month, firstday), culture); 
3

me he dado cuenta de esto cuando el uso de LINQ y llama como Select, dónde, etc., sin una llamada inmediata a .ToList () o ToArray(). Iteradores te meterán en problemas. No son tipos nativos con los que WCF sabe cómo trabajar, como List, Array, etc. Son de tipo WhereEnumerable o algo así. Solo téngalo en cuenta cuando envíe resultados de NHibernate o Entity Framework. Espero que esto ayude a alguien. Me tomó horas averiguarlo.

+1

Lazy loading bit te aquí. – tomfanning

+0

De hecho. Puede devolver IEnumerable y salirse con la evaluación lenta, pero si devuelve un tipo que tiene una instancia de IEnumrable , entonces será mejor que llame a ToList() o bien. Entonces rendimiento 1; rendimiento 2; rendimiento 3; funcionará, pero el nuevo TopLevelObject {Values ​​= alguna secuencia de evaluación lenta} te atrapará. –

6

que estaba recibiendo este error al devolver una gran carga útil, que resultó ser el DataContractSerialiser parando medio curso, ya que había dado en el entorno maxItemsInObjectGraph por defecto, añadiendo el folloing a mi behavour punto final fijado el problema

<dataContractSerializer maxItemsInObjectGraph="2147483647" /> 
0

Alguien en este hilo publicó que agregar este elemento al comportamiento del punto final solucionó el problema.

<dataContractSerializer maxItemsInObjectGraph="2147483647" /> 

Esto funcionó, pero tuvo que ser añadido no sólo al comportamiento de punto final, pero el comportamiento en servicio también (lo cual tiene sentido ya que es donde la serialización se llevará a cabo).

Si solo se agregó al servicio, recibí este error "El número máximo de elementos que se pueden serializar o deserializar en un gráfico de objetos es '65536'. Cambie el gráfico de objetos o aumente la cuota MaxItemsInObjectGraph."

Si se agrega al punto final solo recibo la conexión error inesperadamente cerrado.

1

otra razón: Esta excepción surge si tiene DataContract/DataMember atributos en una Interface en lugar de un tipo concreto (terrible idea, don' t hacerlo) y está tratando de serializar el Concrete type.

1

En mi caso estaba devolviendo un objeto de clase personalizado, uno de los miembros de la cual era una tabla de datos. y si no tienes un nombre en la tabla de datos arrojará este error.

Dim oTable As DataTable = New DataTable 'this wont serialize 
Dim oTable As DataTable = New DataTable("MyTable") 'this will serialize 
Cuestiones relacionadas