Come si configura WCF per supportare FaultContracts in cui sia l'host che il client si trovano nello stesso processo usando net.pipe?

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

Domanda

Sto cercando di creare un test unit in-process per le mie interazioni tra servizio e client utilizzando l'associazione net.pipe. Come un buon servizio WCF, utilizza FaultContractAttribute per le operazioni di servizio per esporre i possibili guasti (eccezioni racchiuse) ai metadati. Vorrei che il client e gli endpoint di servizio fossero configurati tramite XML (App.config). Tuttavia, ogni volta che viene generato un errore, è solo una pipe di CommunicationException "chiusa", e non l'errore tipizzato Mi aspettavo.

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

Ho provato ad aggiungere l'endpoint IMetadataExchange per net.pipe, ma non ha funzionato. Ho anche provato. Quale essere su Vista mi ha richiesto di netsh l'ACL per l'endpoint http. Anche quello non ha funzionato.

La classe di eccezione personalizzata:

public class ValidationException : ApplicationException { }

Questo è l'ultimo tentativo di configurazione, ma elimina " Il nome del contratto 'IMetadataExchange' non è stato trovato nell'elenco dei contratti implementati dal servizio "

Tutti i collegamenti ad esempi o consigli su come ottenere questo risultato sarebbero apprezzati.

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

È stato utile?

Soluzione

Se la classe ValidationException che descrivi sopra è la classe che stai usando per i guasti, potrebbe essere la fonte del tuo problema. È necessario derivare le eccezioni di errore da FaultException perché è serializzabile. ApplicationException no.

Wagner ha ragione, è necessario decorare la definizione dell'operazione con un attributo FaultContract che gli dia il tipo di contratto. Dovresti anche decorare il tuo FaultContract con gli attributi DataContract e DataMember.

Altri suggerimenti

Ho avuto lo stesso errore qualche giorno fa.
Ho risolto creando la mia classe (MyFault) e lanciando FaultException dal server e catturandoli nel client. MyFault ha un membro stringa che è il messaggio di eccezione che voglio che il client veda.

Spero di essermi chiarito ... Proverò a cercare un bel campione e lo pubblicherò qui

Il problema è molto probabilmente un errore che deserializza o serializza la richiesta o la risposta. Abilita la traccia e visualizza il registro con svctraceviewer per l'errore esatto.

Inoltre, assicurati che l'eccezione di errore sia contrassegnata con [DataContract] e non erediti e non le classi [DataContract].

Un'ultima cosa da aggiungere. I contratti operativi definiscono il ServiceFault che stanno utilizzando ?. ??

La mia comprensione è che devi definire quali ServiceFaults stai utilizzando a livello operativo e la tua logica aziendale genera una FaulException dove T è il ServiceFault che hai definito.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top