Inicio rápido de solución de problemas de WCF
En este tema se enumeran muchos problemas conocidos que los clientes han detectado al desarrollar clientes y servicios de WCF. Si el problema que tiene no aparece en esta lista, se recomienda que configure la traza del servicio. De esta forma, se genera un archivo de seguimiento que puede ver con el visor de archivos de seguimiento y obtiene información detallada sobre las excepciones que se pueden producir en el servicio. Para obtener más información sobre la configuración del seguimiento, consulte Configuring Tracing. Para obtener más información sobre cómo usar el visor de archivos de seguimiento, consulte Service Trace Viewer Tool (SvcTraceViewer.exe).
-
Error HTTP 404.3 – No encontrada. La página que solicita no puede presentarse debido a la configuración de la extensión. Si la página es un script, agregue un controlador. Si se descarga el archivo, agregue un mapa MIME. Error detallado InformationModule StaticFileModule.
Mi servicio empieza a rechazar nuevos clientes cuando interactúa con unos 10 clientes. ¿Qué pasa?
¿Cuál es la dirección base? ¿Cómo se relaciona con una dirección de extremo?
Después de instalar Windows 7 e IIS, cuando intente explorar un servicio WCF puede obtener el mensaje de error siguiente: HTTP Error 404.3 – no encontrado
El mensaje de error completo es:
Error HTTP 404.3 – No encontrada. La página que solicita no puede presentarse debido a la configuración de la extensión. Si la página es un script, agregue un controlador. Si se descarga el archivo, agregue un mapa MIME. Error detallado InformationModule StaticFileModule.
Este mensaje de error aparece cuando "Activación HTTP de Windows Communication Foundation" no se establece de manera explícita en el Panel de control. Para establecer esto, vaya al Panel de control y haga clic en Programas en la esquina inferior izquierda de la ventana. Haga clic en Activar o desactivar las características de Windows. Expanda el elemento con la etiqueta Microsoft .NET Framework 3.5.1, seleccione Activación HTTP de Windows Communication Foundation .
A veces recibo una excepción MessageSecurityException en la segunda solicitud si mi cliente está inactivo durante algún tiempo después de la primera solicitud. ¿Qué pasa?
Se puede producir un error en la segunda solicitud principalmente por dos razones: (1) se ha agotado de tiempo de espera de la sesión o (2) se recicla el servidor web que está hospedando el servicio. En el primer caso, la sesión es válida hasta que se agota el tiempo de espera del servicio. Cuando el servicio no recibe una solicitud del cliente dentro del período de tiempo especificado en el enlace del servicio (ReceiveTimeout), el servicio finaliza la sesión de seguridad. Los siguientes mensajes del cliente producen MessageSecurityException. El cliente debe restablecer una sesión segura con el servicio para enviar los futuros mensajes o utilizar un token de contexto de seguridad con estado. Los tokens de contexto de seguridad con estado también permiten que una sesión segura sobreviva a un servidor web que se recicla. Para más información sobre el uso de tokens de contexto de seguridad con estado en una sesión segura, consulte Procedimiento para crear un token de contexto de seguridad con estado para una sesión segura. También puede deshabilitar las sesiones seguras. Al usar el enlace <wsHttpBinding>, puede configurar la propiedad establishSecurityContext
en false
para deshabilitar las sesiones seguras. Para deshabilitar las sesiones seguras para otros enlaces, debe crear un enlace personalizado. Para obtener más información sobre cómo crear un enlace personalizado, consulte How to: Create a Custom Binding Using the SecurityBindingElement. Antes de aplicar cualquiera de estas opciones, debe entender los requisitos de seguridad de su aplicación.
Mi servicio empieza a rechazar nuevos clientes cuando interactúa con unos 10 clientes. ¿Qué pasa?
De forma predeterminada, los servicios pueden tener solo 10 sesiones simultáneas. Por tanto, si los enlaces del servicio utilizan sesiones, el servicio acepta nuevas conexiones de cliente hasta que alcance ese numero, después del cual rechaza nuevas conexiones de cliente hasta que finaliza una de las sesiones actuales. Puede admitir más clientes de varias maneras. Si su servicio no requiere sesiones, no utilice un enlace con sesión. (Para más información, consulte Uso de sesiones). Otra opción es aumentar el límite de sesiones cambiando el valor de la propiedad MaxConcurrentSessions al número adecuado a sus circunstancias.
¿Puedo cargar mi configuración de servicio desde otra parte que no sea el archivo de configuración de la aplicación WCF?
Sí, sin embargo, tiene que crear una clase ServiceHost personalizada que invalide el método ApplyConfiguration . Dentro de ese método, puede llamar a la base para cargar primero la configuración (si desea también cargar la información de configuración estándar), pero también puede reemplazar completamente el sistema de carga de configuración. Si desea cargar la configuración desde un archivo de configuración que es diferente del archivo de configuración de la aplicación, debe analizar usted mismo el archivo de configuración y cargar la configuración.
El siguiente ejemplo de código muestra cómo invalidar el método ApplyConfiguration y configurar directamente un extremo.
public class MyServiceHost : ServiceHost
{
public MyServiceHost(Type serviceType, params Uri[] baseAddresses)
: base(serviceType, baseAddresses)
{
Console.WriteLine("MyServiceHost Constructor");
}
protected override void ApplyConfiguration()
{
string straddress = GetAddress();
Uri address = new Uri(straddress);
Binding binding = GetBinding();
base.AddServiceEndpoint(typeof(IData), binding, address);
}
string GetAddress()
{
return "http://MyMachine:7777/MyEndpointAddress/";
}
Binding GetBinding()
{
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.None;
return binding;
}
}
Mi servicio y cliente funcionan muy bien, pero no puedo conseguir que funcionen cuando el cliente está en otro equipo. ¿Qué sucede?
Dependiendo de la excepción, puede haber varios problemas:
Puede que necesite cambiar las direcciones de extremo del cliente al nombre de host y no el "localhost".
Puede que necesite abrir el puerto a la aplicación. Para obtener más información, consulte Firewall Instructions en los ejemplos de SDK.
Para otros problemas posibles, consulte el tema de los ejemplos Ejecución de los ejemplos de Windows Communication Foundation.
Si su cliente está utilizando las credenciales de Windows y la excepción es SecurityNegotiationException, configure Kerberos tal y como se muestra a continuación.
Agregue las credenciales de identidad al elemento de extremo en el archivo del cliente App.config:
<endpoint address="http://MyServer:8000/MyService/" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IServiceExample" contract="IServiceExample" behaviorConfiguration="ClientCredBehavior" name="WSHttpBinding_IServiceExample"> <identity> <userPrincipalName value="name@corp.contoso.com"/> </identity> </endpoint>
Ejecute el servicio autohospedado con la cuenta System o NetworkService. Puede ejecutar este comando para crear una ventana de comandos bajo la cuenta del sistema:
at 12:36 /interactive "cmd.exe"
Hospede el servicio bajo IIS (Servicios de Internet Information Services) (IIS) que, de forma predeterminada, utiliza la cuenta del nombre de entidad de seguridad de servicio (SPN).
Registre un nuevo SPN con el dominio utilizando SetSPN. Para hacerlo, debe ser administrador de dominio.
Para más información sobre el protocolo Kerberos, consulte Conceptos de seguridad empleados en WCF y:
Cuando genero una excepción FaultException<Exception> en la que el tipo es una excepción, siempre recibo un tipo FaultException general en el cliente y no el tipo genérico. ¿Qué sucede?
Es muy recomendable que cree su propio tipo de datos de error personalizado y lo declare como tipo detallado en el contrato de error. La razón es que utilizando los tipos de excepción proporcionados por el sistema:
Crea una dependencia de tipo que quita uno de los puntos fuertes más grandes de las aplicaciones orientadas al servicio.
No se puede esperar que las excepciones se serialicen de una manera estándar. Puede que algunas, como SecurityExceptionno se puedan serializar en absoluto.
Expone los detalles internos de la implementación a los clientes. Para más información, consulte Especificación y administración de errores en contratos y servicios.
Si está depurando una aplicación, sin embargo, puede serializar información de excepción y devolverla al cliente utilizando la clase ServiceDebugBehavior .
Parece que las operaciones unidireccionales y las operaciones solicitud-respuesta se devuelven aproximadamente a la misma velocidad cuando la respuesta no contiene datos. ¿Qué sucede?
Especificando que una operación es unidireccional solo significa que el contrato de operación acepta un mensaje de entrada y no devuelve un mensaje de salida. En WCF, todas las invocaciones del cliente vuelven cuando los datos salientes se han escrito en la conexión o se produce una excepción. Las operaciones unidireccionales funcionan de la misma manera y se pueden iniciar si el servicio no se puede localizar o se pueden bloquear si el servicio no está preparado para aceptar los datos de la red. Por lo general, en WCF, se generan llamadas unidireccionales que vuelven al cliente más rápidamente que la solicitud-respuesta; pero las condiciones que ralentizan el envío de los datos salientes a través de la red ralentizan las operaciones unidireccionales, así como las operaciones de solicitud-respuesta. Para más información, consulte Servicios unidireccionales y Acceso a servicios mediante un cliente WCF.
Estoy usando un certificado X.509 con mi servicio y obtengo una excepción System.Security.Cryptography.CryptographicException. ¿Qué sucede?
Esto se produce normalmente después de cambiar la cuenta de usuario bajo la cual se ejecuta el proceso de trabajo de IIS. Por ejemplo, en Windows XP, si cambia la cuenta de usuario predeterminada que Aspnet_wp.exe ejecuta desde ASPNET a una cuenta de usuario personalizada, puede ver este error. Si utiliza una clave privada, el proceso que utiliza necesitará tener los permisos para tener acceso al archivo que almacena esa clave.
Si éste es el caso, debe dar los privilegios de acceso de lectura a la cuenta del proceso para el archivo que contiene la clave privada. Por ejemplo, si el proceso de trabajo de IIS se está ejecutando bajo la cuenta Bob, entonces, necesitará proporcionar a Bob el acceso de lectura al archivo que contiene la clave privada.
Para más información sobre cómo proporciona a la cuenta de usuario correcta acceso al archivo que contiene la clave privada para un certificado X.509 concreto, consulte Conversión de los certificados X.509 en accesibles para WCF.
He cambiado el primer parámetro de una operación de mayúsculas a minúsculas; ahora mi cliente produce una excepción. ¿Qué sucede?
Los valores de los nombres de parámetro en la firma de la operación forma parte del contrato y distingue entre mayúsculas y minúsculas. Utilice el atributo System.ServiceModel.MessageParameterAttribute cuando necesite distinguir entre el nombre de parámetro local y los metadatos que describen la operación para las aplicaciones cliente.
Estoy utilizando una de mis herramientas de traza y obtengo la excepción EndpointNotFoundException. ¿Qué sucede?
Si utiliza una herramienta de seguimiento que no es el mecanismo de seguimiento de WCF proporcionado por el sistema y recibe una excepción EndpointNotFoundException que indica que no coincide con el filtro de direcciones, necesita utilizar la clase ClientViaBehavior para dirigir los mensajes a la utilidad de seguimiento y permitir que esta redirija esos mensajes a la dirección del servicio. La clase ClientViaBehavior modifica Via
que dirige el encabezado para especificar la siguiente dirección de red de forma independiente con respecto al receptor último, indicado por To
que dirige el encabezado. Cuando haga esto, sin embargo, no cambie la dirección del extremo, la cual se utiliza para establecer el valor To
.
El ejemplo de código siguiente muestra un ejemplo de archivo de configuración de cliente.
<endpoint
address="http://localhost:8000/MyServer/"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IMyContract"
behaviorConfiguration="MyClient"
contract="IMyContract"
name="WSHttpBinding_IMyContract">
</endpoint>
<behaviors>
<endpointBehaviors>
<behavior name="MyClient">
<clientVia viaUri="http://localhost:8001/MyServer/"/>
</behavior>
</endpointBehaviors>
</behaviors>
¿Cuál es la dirección base? ¿Cómo se relaciona con una dirección de extremo?
Una dirección base es la dirección de raíz para una clase ServiceHost . De forma predeterminada, si agrega una clase ServiceMetadataBehavior en su configuración de servicio, el lenguaje de descripción de servicios Web (WSDL) para todos los extremos que publica el host se recupera de la dirección base de HTTP, más cualquier dirección relativa proporcionada al comportamiento de los metadatos, más "? wsdl". Si está familiarizado con ASP.NET e IIS, la dirección base es equivalente al directorio virtual.
Compartir un puerto entre un extremo de servicio y un extremo mex mediante NetTcpBinding
Si especifica la dirección base para un servicio como net.tcp://MyServer:8080/MyService y agrega los siguientes extremos:
<services>
<service name="Microsoft.Samples.NetTcp.CalculatorService">
<endpoint address="calcsvc" binding ="netTcpBinding" contract="Microsoft.Samples.NetTcp.ICalculator"/>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
</service>
</services>
Y si modifica uno de los valores de NetTcpBinding como se muestra en el siguiente fragmento de código de configuración:
<bindings>
<netTcpBinding>
<binding closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="11" maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
</security>
</binding>
</netTcpBinding>
</bindings>
Verá un error como el siguiente: Excepción no controlada: System.ServiceModel.AddressAlreadyInUseException: Ya hay una escucha en el extremo IP0.0.0.0:9000. Para solucionar este error, especifique una dirección URL completa con un puerto diferente para el extremo MEX, como se muestra en el siguiente fragmento de código de configuración:
<services>
<service name="Microsoft.Samples.NetTcp.CalculatorService">
<endpoint address="calcsvc" binding ="netTcpBinding" contract="Microsoft.Samples.NetTcp.ICalculator"/>
<endpoint address="net.tcp://localhost:9001/servicemodelsamples/mex" binding="mexTcpBinding" contract="IMetadataExchange" />
</service>
</services>
Al llamar a una aplicación web HTTP de WCF desde una aplicación SOAP de WCF, el servicio devuelve el siguiente error: 405 Método no permitido
Llamar a una aplicación web HTTP de WCF (un servicio que usa WebHttpBinding y WebHttpBehavior) desde un servicio WCF puede generar la excepción siguiente: Unhandled Exception: System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: The remote server returned an unexpected response: (405) Method Not Allowed.
Esta excepción se produce porque WCF sobrescribe el OperationContext saliente por el OperationContext entrante. Para resolver este problema, cree un OperationContextScope dentro de la operación del servicio web HTTP de WCF. Por ejemplo:
public string Echo(string input)
{
using (new OperationContextScope(this.InnerChannel))
{
return base.Channel.Echo(input);
}
}