Comment configurez-vous WCF pour prendre en charge FaultContracts lorsque l'hôte et le client sont dans le même processus à l'aide d'un net.pipe?

StackOverflow https://stackoverflow.com/questions/220401

Question

J'essaie de créer un test d'unité en cours de traitement pour mes interactions service à client à l'aide de la liaison net.pipe. Comme un bon service WCF, il utilise FaultContractAttribute sur des opérations de service pour exposer les erreurs possibles (exceptions encapsulées) aux métadonnées. Je souhaite que les points de terminaison client et service soient configurés via XML (App.config). Toutefois, chaque fois qu'une erreur est renvoyée, il s'agit simplement d'une communication CommunicationException ", le canal est fermé", et non l'erreur type Je m'attendais.

System.ServiceModel.CommunicationException: There was an error reading from the pipe: The pipe has been ended. (109, 0x6d). 

J'ai essayé d'ajouter un noeud final IMetadataExchange pour net.pipe, mais cela n'a pas fonctionné. J'ai aussi essayé. Le fait d’être sur Vista m'a obligé à utiliser la liste de contrôle d'accès pour le noeud final http. Cela aussi n'a pas fonctionné.

La classe d'exception personnalisée:

public class ValidationException : ApplicationException { }

Il s'agit de la dernière tentative de configuration, mais elle expulse "Le nom du contrat 'IMetadataExchange' est introuvable dans la liste des contrats implémentés par le service"

Tous les liens vers des exemples ou des recommandations sur la manière de procéder seraient appréciés.

<system.serviceModel>

  <client>
    <endpoint name="Client"
              contract="IService"
              address="net.pipe://localhost/ServiceTest/"
              binding="netNamedPipeBinding"
              bindingConfiguration="netPipeBindingConfig" />
  </client>

  <services>
    <service
      name="Service"
      behaviorConfiguration="ServiceFaults">
      <host>
        <baseAddresses>
          <add baseAddress="net.pipe://localhost/ServiceTest/"/>
          <add baseAddress="http://localhost/ServiceTest/"/>
        </baseAddresses>
      </host>
      <endpoint
        address=""
        binding="netNamedPipeBinding"
        bindingConfiguration="netPipeBindingConfig"

        name="ServicePipe"
        contract="IService" />
      <endpoint
        address="MEX"
        binding="mexNamedPipeBinding"
        bindingConfiguration="mexNetPipeBindingConfig"
        name="MexUserServicePipe"
        contract="IMetadataExchange" />
    </service>
  </services>

  <bindings>
    <netNamedPipeBinding>
      <binding name="netPipeBindingConfig"
               closeTimeout="00:30:00"
               sendTimeout="00:30:00" />
    </netNamedPipeBinding>
    <mexNamedPipeBinding>
      <binding name="mexNetPipeBindingConfig"></binding>
    </mexNamedPipeBinding>
  </bindings>

  <behaviors>
    <serviceBehaviors>
      <behavior name="ServiceFaults">
        <serviceDebug includeExceptionDetailInFaults="true"/>
      </behavior>
      <behavior name="MEX">
        <serviceMetadata 
          httpGetEnabled="true"
          httpGetUrl="http://localhost/ServiceTest/MEX"/>
      </behavior>
    </serviceBehaviors>
  </behaviors>

</system.serviceModel>

Était-ce utile?

La solution

Si la classe ValidationException que vous décrivez ci-dessus est la classe que vous utilisez pour les erreurs, cela peut être la source de votre problème. Vous devez dériver vos exceptions de faute de FaultException car il est sérialisable. ApplicationException n'est pas.

Wagner a raison, vous devez décorer votre définition d’opération avec un attribut FaultContract en lui donnant le type de votre contrat. Vous devez également décorer votre FaultContract avec les attributs DataContract et DataMember également.

Autres conseils

J'ai eu la même erreur il y a quelques jours.
J'ai résolu de créer ma propre classe (MyFault) et de lancer FaultException du serveur et de les récupérer dans le client. MyFault a un membre de chaîne qui est le message d'exception que je veux que le client voie.

J'espère avoir été clair ... Je vais essayer de trouver un bon échantillon et le poster ici

Le problème est probablement une erreur de désérialisation ou de sérialisation de la demande ou de la réponse. Activez la trace et affichez le journal avec svctraceviewer pour l’erreur exacte.

Assurez-vous également que votre exception d'erreur est marquée avec [DataContract] et qu'elle n'hérite pas des classes autres que [DataContract].

Une dernière chose à ajouter. Vos contrats d’exploitation définissent-ils le ServiceFault qu’ils utilisent?.

Je crois comprendre que vous devez définir les ServiceFaults que vous utilisez au niveau de la couche opération et que votre logique métier lève une exception FaulException où T est le ServiceFault que vous avez défini.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top