L’object de communication System.ServiceModel.Channels.ServiceChannel ne peut pas être utilisé pour la communication

L’object de communication, System.ServiceModel.Channels.ServiceChannel, ne peut pas être utilisé pour la communication car il est dans l’état Faulted.

Quelle est cette erreur, et comment pourrais-je y remédier?

Vous obtenez cette erreur parce que vous avez laissé une exception .NET se produire côté serveur et que vous ne l’avez pas interceptée et traitée, et que vous ne l’avez pas non plus convertie en une erreur SOAP.

Maintenant que le serveur a “bombardé”, le runtime WCF a “endommagé” le canal – par exemple, le lien de communication entre le client et le serveur est inutilisable – après tout, il semble que votre serveur a explosé. ça plus.

Donc, ce que vous devez faire c’est:

  • toujours attraper et gérer vos erreurs côté serveur – ne laissez pas les exceptions .NET voyager du serveur vers le client – toujours envelopper ces fautes SOAP interopérables. Découvrez l’interface WCR IErrorHandler et implémentez-la côté serveur

  • Si vous êtes sur le point d’envoyer un deuxième message sur votre chaîne à partir du client, assurez-vous que le canal n’est pas dans l’état défectueux:

    if(client.InnerChannel.State != System.ServiceModel.CommunicationState.Faulted) { // call service - everything's fine } else { // channel faulted - re-create your client and then try again } 

    Si c’est le cas, tout ce que vous pouvez faire est de s’en débarrasser et de recréer à nouveau le proxy côté client, puis réessayez.

Pour empêcher le serveur de tomber en état de panne, vous devez vous assurer qu’aucune exception non gérée n’est déclenchée. Si WCF voit une exception inattendue, plus aucun appel n’est accepté – la sécurité d’abord.
Deux possibilités pour éviter ce comportement:

  1. Utilisez une exception FaultException (celle-ci n’est pas inattendue pour WCF, le WCF sait donc que le serveur a toujours un état valide)
    au lieu de

     throw new Exception("Error xy in my function") 

    utiliser toujours

     throw new FaultException("Error xy in my function") 

    peut-être vous pouvez essayer..catch le bloc entier et lancer une exception de défaut dans tous les cas d’une exception

     try { ... some code here } catch (Exception ex) { throw new FaultException(ex.Message) } 
  2. Indiquez à WCF de gérer toutes les exceptions à l’aide d’un gestionnaire d’erreur. Cela peut être fait de plusieurs manières, j’ai choisi un simple en utilisant un atsortingbut:
    Tout ce que nous avons à faire est d’utiliser l’atsortingbut [SvcErrorHandlerBehaviour] sur l’implémentation de service souhaitée.

     using System; using System.Collections.ObjectModel; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; namespace MainService.Services { ///  /// Provides FaultExceptions for all Methods Calls of a Service that fails with an Exception ///  public class SvcErrorHandlerBehaviourAtsortingbute : Atsortingbute, IServiceBehavior { public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } //implementation not needed public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection endpoints, BindingParameterCollection bindingParameters) { } //implementation not needed public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { foreach (ChannelDispatcherBase chanDispBase in serviceHostBase.ChannelDispatchers) { ChannelDispatcher channelDispatcher = chanDispBase as ChannelDispatcher; if (channelDispatcher == null) continue; channelDispatcher.ErrorHandlers.Add(new SvcErrorHandler()); } } } public class SvcErrorHandler: IErrorHandler { public bool HandleError(Exception error) { //You can log th message if you want. return true; } public void ProvideFault(Exception error, MessageVersion version, ref Message msg) { if (error is FaultException) return; FaultException faultException = new FaultException(error.Message); MessageFault messageFault = faultException.CreateMessageFault(); msg = Message.CreateMessage(version, messageFault, faultException.Action); } } } 

C’est un exemple simple, vous pouvez approfondir IErrorhandler en n’utilisant pas FaultException nu, mais une FaultException<> avec un type fournissant des informations supplémentaires, voir IErrorHandler pour un exemple détaillé.

En fait, en cas d’échec après avoir suivi les suggestions de marc_s , gardez à l’esprit qu’un élément dans la configuration de liaison du serveur (ou son absence) dans web.config sur le serveur peut provoquer cette exception. Par exemple, le serveur attend la sécurité au niveau du Message et le client est configuré sur None (ou, si le serveur ne fait pas partie d’un domaine Active Directory mais que l’hôte du client distant l’est).

Conseil: dans de tels cas, l’application client appellera très probablement le service Web correctement lorsqu’il est exécuté directement sur le serveur sous un compte administratif dans une session RDP.

Joindre à l’événement faulted pour savoir pourquoi et quand l’erreur s’est produite.

Edit: Il serait également utile que vous publiiez plus d’informations sur ce que vous faites.

Pour diagnostiquer ce problème, exécutez le service sous le débogueur Visual Studio. Utilisez le menu: Debug | Exceptions et indiquez que vous souhaitez interrompre une exception.

L’exception d’origine renvoyée aura un message d’erreur bien meilleur que “..il est à l’état de défaillance”.

Par exemple, je recevais cette exception de ServiceHost.Open (), mais lorsque j’ai détecté l’exception d’origine au moment où elle a été lancée, le message d’erreur était le suivant:

Le service ‘MyServiceName’ n’a aucun sharepoint terminaison d’application (non-infrastructure). Cela peut être dû au fait qu’aucun fichier de configuration n’a été trouvé pour votre application ou parce qu’aucun élément de service correspondant au nom du service n’a pu être trouvé dans le fichier de configuration ou qu’aucun sharepoint terminaison n’a été défini dans l’élément de service.

La correction de la faute d’orthographe dans App.config a résolu le problème.

J’ai un client Web qui se connecte au service Windows via WCF. mon application web jette la même erreur

L’object de communication System.ServiceModel.Channels.ServiceChannel ne peut pas être utilisé pour la communication car il est à l’état Défaillance J’ai activé le traçage WCF, ce qui n’était pas d’une grande aide. le redémarrage du service Windows l’a finalement résolu et je n’ai toujours aucune idée de la cause. Le dépannage doit donc toujours être simple. C’est un bon exemple. Si quelqu’un a un problème similaire, essayez de redémarrer le service.

J’ai eu un autre problème, que je ne pense pas avoir été mentionné dans les autres réponses.

Je dois entretenir les points de terminaison sur la même adresse TCP et le même port. Dans app.config, j’avais oublié d’append les deux points de terminaison. Le service s’exécutait donc sur le bon port, mais avec une mauvaise interface de service.

Si vous voyez ce message dans Debug à partir de Visual Studio et que la solution contient un projet WCF. Ouvrez ensuite les parameters de ce projet WCF -> allez dans l’onglet “Options WCF” -> désactivez l’option “Démarrer l’hôte de service WCF lors du débogage …”

Dans mon cas, la raison était un mauvais certificate qui ne pouvait pas être chargé. Je l’ai découvert à partir de l’Observateur d’événements, sous Système:

Une erreur fatale s’est produite lors de la tentative d’access à la clé privée d’informations d’identification du serveur TLS. Le code d’erreur renvoyé par le module cryptographique est 0x8009030D. L’état d’erreur interne est 10001.

Cette erreur peut être déclenchée par votre propre ordinateur, et pas seulement par une exception non gérée. Si l’heure et l’horloge de votre serveur / ordinateur sont trop longues, de nombreux services Web .NET rejetteront votre demande avec une erreur non gérée. Il est géré de leur sharepoint vue, mais pas géré de votre sharepoint vue. Vérifiez que l’heure de votre serveur de réception est correcte. S’il doit être corrigé, vous devrez réinitialiser votre service ou redémarrer avant la réouverture du canal.

J’ai rencontré ce problème sur un serveur où le pare-feu a bloqué la mise à jour de l’heure Internet et le serveur s’est arrêté pour une raison quelconque. Tous les services Web .NET tiers ont échoué car ils ont rejeté toute demande de service Web. Entrer dans l’observateur d’événements a permis d’identifier le problème, mais l’ajustement de l’horloge l’a résolu. L’erreur était sur notre fin même si nous avons reçu le message d’erreur État défectueux pour les futurs appels de service Web.

Le serveur interrompt automatiquement les connexions sur lesquelles aucun message n’a été reçu pendant la durée égale à la temporisation de réception ( 10 minutes par défaut ). Il s’agit d’une atténuation de DoS pour empêcher les clients de forcer le serveur à avoir des connexions ouvertes pour une durée indéterminée.

Comme le serveur interrompt la connexion parce qu’il est inactif, le client obtient cette exception.

Vous pouvez contrôler la durée pendant laquelle le serveur permet à une connexion de restr inactive avant de l’abandonner en configurant le délai de réception sur la liaison du serveur. Crédit: TRVishwanath – MSFT

Ce n’est pas une solution à ce problème, mais si vous rencontrez l’erreur ci-dessus avec Ektron eSync, il se peut que votre firebase database manque d’espace disque.

Edit: En fait, cela ne concerne pas uniquement Ektron eSync. Cela pourrait se produire sur n’importe quel service qui interroge une firebase database complète.

Modifier: L’espace disque insuffisant ou le blocage de l’access à un répertoire dont vous avez besoin provoquera ce problème.