Inicio rápido de solución de problemas de WCF

Este tema utiliza un formato pregunta y respuesta para describir algunos de los problemas más comunes que se producen, qué puede hacer usted para resolverlos y dónde buscar más información sobre el problema.

Preguntas

Pregunta: A veces recibo MessageSecurityException en la segunda solicitud si mi cliente está inactivo durante algún tiempo después de la primera solicitud. ¿Qué sucede?

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 está siendo reciclado. Para obtener más información acerca de utilizando los tokens del contexto seguros con estado en una sesión segura, consulte How to: Create a Stateful Security Context Token for a Secure Session. También puede deshabilitar las sesiones seguras. Al utilizar el enlace WsHttpBinding, puede establecer 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 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.

Pregunta: Mi servicio empieza a rechazar nuevos clientes después de la interacción de, aproximadamente, 10 clientes. ¿Qué sucede?

De forma predeterminada, los servicios pueden tener sólo 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 obtener más información, vea Using Sessions.) Otra opción es aumentar el límite de sesión cambiando el valor de la propiedad MaxConcurrentSessions al número apropiado a su circunstancia.

Pregunta: ¿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 invalida 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. Tenga en cuenta que 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;
  }
}

Pregunta: Mi servicio y cliente funcionan muy bien, pero no puedo conseguir que funcionen cuando el cliente está en otro PC. ¿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 información, consulte Instrucciones de firewall de los ejemplos de SDK.

  • Para otros posibles problemas, consulte el tema de los ejemplos, Ejecución de ejemplos en un grupo de trabajo y entre los equipos.

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

    1. 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>
      
    2. Ejecute el servicio autohospedado bajo el Sistema o cuenta de NetworkService. Puede ejecutar este comando para crear una ventana de comandos bajo la cuenta del sistema:

      at 12:36  /interactive "cmd.exe"
      
    3. Hospede el servicio bajo IIS (Servicios de Internet Information Services) (IIS) que, de forma predeterminada, utiliza la cuenta del nombre principal de servicio (SPN).

    4. Registre un nuevo SPN con el dominio utilizando SetSPN. Tenga en cuenta que, para ello, necesitará ser un administrador de dominio.

Para obtener más información acerca de el protocolo Kerberos, consulte Security Concepts Used in WCF y:

Pregunta: Cuando inicio una <Excepción FaultException> donde 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 el tipo de detalle en su 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 puede depender de las excepciones que serializan de una manera estándar. Puede que algunas, como SecurityException no se puedan serializar en absoluto.

  • Expone los datos de implementación interna a los clientes. Para obtener más información, vea Specifying and Handling Faults in Contracts and Services.

Si está depurando una aplicación, sin embargo, puede serializar información de excepción y devolverla al cliente utilizando la clase ServiceDebugBehavior.

Pregunta: Parece que las operaciones unidireccionales y las operaciones solicitud-respuesta devuelven aproximadamente la misma velocidad cuando la respuesta no contiene datos. ¿Qué sucede?

Especificando que una operación es unidireccional sólo 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. Normalmente en WCF, esto produce 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 solicitud-respuesta. Para obtener más información, vea One-Way Services y Consuming Services Using a Client.

Pregunta: Estoy utilizando un certificado X.509 con mi servicio y obtengo un 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 obtener más información acerca de cómo proporcionar a la cuenta de usuario correcta acceso al archivo que contiene la clave privada para un certificado X.509 concreto, consulte How to: Make X.509 Certificates Accessible to WCF.

Pregunta: 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?

El valor 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 del cliente.

Pregunta: Estoy utilizando una de mis herramientas de seguimiento y obtengo EndpointNotFoundException. ¿Qué sucede?

Si está utilizando una herramienta de seguimiento que no es el mecanismo de seguimiento WCF proporcionado por el sistema y usted recibe EndpointNotFoundException que indica que había una desigualdad de filtro de dirección, necesita utilizar la clase ClientViaBehavior para dirigir los mensajes a la utilidad de seguimiento y hacer que la utilidad redirija esos mensajes a la dirección de 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=https://localhost:8000/MyServer/
  binding="wsHttpBinding"
  bindingConfiguration="WSHttpBinding_IMyContract"
  behaviorConfiguration="MyClient" 
  contract="IMyContract" 
  name="WSHttpBinding_IMyContract">
</endpoint>
<behaviors>
  <endpointBehaviors>
    <behavior name="MyClient">
      <clientVia viaUri="https://localhost:8001/MyServer/"/>
    </behavior>
  </endpointBehaviors>
</behaviors>

Pregunta: ¿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 la host publica se recuperan de la dirección base de Http, más cualquier dirección proporcionada relativa 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.

Pregunta: ¿Cómo expongo varios extremos a un servicio?

Puede hacerlo agregando los elementos <endpoint> al elemento <service> en un archivo de configuración de aplicación o llevando a cabo los pasos equivalentes mediante programación. Para obtener más información, vea , Specifying an Endpoint Address, How to: Create a Service Endpoint in Configuration y How to: Create a Service Endpoint in Code.

Pregunta: ¿Cómo sé qué enlaces admiten comportamientos diferentes?

Para obtener más información acerca de los enlaces proporcionados por el sistema y las características que admiten, consulte System-Provided Bindings.

Pregunta: ¿Cómo configuro un enlace estándar con valores diferentes para cualquiera de los atributos?

Para obtener más información, consulte Configuring Bindings for Windows Communication Foundation Services.

Pregunta: ¿Necesito implementar mi servicio a un servidor HTTP si deseo utilizar Http como el transporte?

No. Los enlaces proporcionados por el sistema incluyen varios que admiten transportes HTTP cuando se utilizan desde cualquier tipo de aplicación host. Para obtener más información acerca de los enlaces proporcionados por el sistema y las características que admiten, consulte System-Provided Bindings.

Pregunta: ¿Cuál es el comportamiento predeterminado de un servicio que utiliza enlaces estándar?

Depende del enlace estándar elegido. En general, el comportamiento predeterminado de los enlaces que utilizan sesiones es crear una nueva instancia de servicio para cada nuevo cliente y las llamadas posteriores de un cliente determinado se dirigen hacia la instancia del servicio asociada. Para obtener más información acerca de los enlaces proporcionados por el sistema y las características que admiten, consulte System-Provided Bindings.

Pregunta: ¿Hay una manera fácil de ver la asignación de características a los enlaces? Por ejemplo, ¿cómo puedo indicar qué enlaces admiten transacciones, seguridad, etc.?

Sí. Consulte System-Provided Bindings.

Pregunta: ¿Cómo paso los tipos de datos personalizados desde un servicio a un cliente?

Los tipos de datos pasados entre dos extremos deben ser serializables y el mecanismo de serialización más fácil y más interoperable para los servicios es utilizar DataContractAttribute y las clases DataMemberAttribute. Para obtener más información acerca de esto y otros mecanismos de serialización compatibles, consulte Specifying Data Transfer in Service Contracts.

Pregunta: ¿Cuándo debería configurar algo utilizando un archivo de configuración y cuándo debería configurarlo en código?

Dado que un archivo de configuración de aplicación permite al programador colocar las decisiones sobre configuración en tiempo de ejecución en manos del implementador, las decisiones que los implementadores nunca deberían tomar son buenas candidatas para la configuración en el código de producto. Los implementadores pueden ser individuos que instalan los programas en sus propios equipos o administradores de empresas que utilizan las directivas de grupo de la empresa para modificar los archivos de configuración del equipo y bloquearlos contra la modificación local. Para obtener un ejemplo del último caso, consulte How to: Lockdown Endpoints in the Enterprise.

Pregunta: ¿Qué debería saber sobre el diseño de un servicio con buen comportamiento?

Consulte Designing and Implementing Services.

Pregunta: ¿Qué es todo este material en el código de cliente generado?

Para familiarizarse con el código de cliente generado, vea Understanding Generated Client Code. Para obtener más información acerca de la arquitectura cliente, vea WCF Client Architecture.

Pregunta: ¿Por qué debería llamar al método Close en el objeto de cliente de WCF?

Llamar Close en el objeto de cliente WCF habilita el cliente y servicio a concluir correctamente la conversación y reciclar los recursos asociados a él. Además, si está utilizando sesiones, llamar Close puede ser la manera más rápida de determinar si la sesión ha fallado desde la última llamada, un escenario que puede tener significado para su aplicación cliente. Para obtener más información, vea Consuming Services Using a WCF Client y Excepciones esperadas de ejemplo.

Pregunta: ¿Por qué mi servicio no se ejecuta como se espera incluso cuándo parece haber ningún problema en el código?

Si su aplicación de servicio se configura utilizando un archivo de configuración de aplicación, debería examinar ese archivo para determinar si algún elemento de configuración o el atributo está modificando el comportamiento de ejecución de forma inesperada. En particular, el comportamiento de tiempo de ejecución depende bastante del enlace que implementa el contrato en un extremo. Confirme que el enlace en el archivo de configuración admite las características que desea y en el modo que espera.

Si parece que no hay ningún problema en el archivo de configuración, puede continuar examinando el comportamiento de tiempo de ejecución de su aplicación utilizando características de diagnóstico, como registro y seguimiento. Para obtener más información, vea Administration and Diagnostics.

Pregunta: ¿Cuál es la mejor manera de indicar a un cliente que algo ha fallado en el servicio?

La mejor manera es agregar una clase FaultContractAttribute con un tipo de datos de error serializable personalizado a su operación. A continuación, cuando su operación se encuentra con una condición de error que puede detectar, inicia un nuevo FaultException donde el parámetro de tipo es el tipo de error serializable. Para obtener más información, vea Specifying and Handling Faults in Contracts and Services.

Pregunta: ¿Qué información es correcta para devolver al cliente?

Devuelva sólo la información que los clientes de su servicio necesitan saber. Como diseñador del servicio, debería proporcionar sólo esa cantidad de información y nada más para minimizar la exposición de datos de implementación internos a clientes no autorizados. Ésta es la razón por la cual se recomienda encarecidamente que no devuelva los objetos Exception en sus errores de SOAP. Para obtener más información, vea Specifying and Handling Faults in Contracts and Services.

Pregunta: ¿Cómo detecta mi aplicación cliente que se ha cerrado una conexión a un servicio?

Puede administrar los eventos de cambio de estado de canal de cliente CommunicationObject; sin embargo, que se le notifique del cierre o fallo de un canal depende de la implementación del canal. Por ejemplo, una clase NetTcpBinding le notifica bastante rápidamente que el canal está cerrado o ha fallado porque la duración de su sesión está asociada a la duración del socket subyacente.

Sin embargo, mientras intenta restablecer la sesión, puede que no se le notifique durante algún tiempo un enlace con sesión diseñado para proteger la aplicación contra pequeñas perturbaciones de la red, como la sesión proporcionada por la clase ReliableSessionBindingElement. Dado que éste es el caso, se recomienda que no intente detectar directamente la desconexión.

En su lugar, trate la sesión como una conversación. Si abre el canal, realiza varias llamadas de operación y cierra correctamente el canal, puede suponer que el canal no se cerró inesperadamente. Para obtener más información acerca de los clientes y sesiones, vea Using Sessions. Para obtener más información acerca de el control de excepciones en el cliente relacionadas con canales, vea Consuming Services Using a Client. Para obtener información sobre el control de excepciones en general, consulte Specifying and Handling Faults in Contracts and Services.

Pregunta: ¿Cómo configuro un certificado de Capa de sockets seguros para la seguridad del servicio WCF?

Consulte How To: Configure a Port with An SSL Certificate.

Pregunta: ¿Cómo utilizo inspectores de mensaje para registrar o modificar el mensaje?

Consulte los temas siguientes:

Pregunta: ¿Cómo agrego una dirección de extremo que tiene información adicional?

Cuando quiere asociar mediante programación las direcciones del extremo complejas (por ejemplo, si necesita especificar mediante programación una clase EndpointAddress que contiene un encabezado concreto o identidad), debe hacer lo siguiente, donde relativeOrAbsoluteAddress es un Identificador uniforme de recursos relativo (URI) o absoluto:

// Do this:
ServiceEndpoint e = myServiceHost.AddServiceEndpoint(c,b,"relativeOrAbsoluteAddress");
e.Address = new EndpointAddress(e.Address.Uri, /*other info like headers */);

Pregunta: Estoy intentado generar un ejemplo hospedado en Web y la generación falla debido a un error del comando crear directorio, copiar o eliminar. ¿Por qué este sucediendo esto?

Como parte del proceso de generación, algunos ejemplos hospedados en Web intentan copiar binarios del servicio WCF compilado a la carpeta %SystemDrive%\inetpub\wwwroot\ServiceModelSamples. Este método implementa de manera eficaz el servicio en IIS. Si la cuenta bajo la que se ejecuta el símbolo de comando SDK o Visual Studio no tiene permiso para modificar la carpeta, la generación se interrumpirá. Para corregirlo, realice una de las acciones siguientes

  • Otorgue el permiso de modificación para %SystemDrive%\inetpub\wwwroot a la cuenta bajo la que está generando el ejemplo.

    O bien

  • Ejecute el símbolo de comando SDK o Visual Studio como un administrador.

Consulte también

Otros recursos

Debugging Windows Authentication Errors

Footer image

Copyright © 2007 Microsoft Corporation. Reservados todos los derechos.