2010-04-05 11 views
8

Sto cercando di far funzionare un servizio WCF-over-TCP. Avevo qualche problema con la modifica del mio progetto, quindi ho pensato di iniziare con il modello WCF "base" incluso in VS2008.mexTcpBinding in WCF - Errori IMetadataExchange

Ecco l'iniziale WCF App.config e quando faccio funzionare il servizio WCF test client può lavorare con esso bene:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.web> 
     <compilation debug="true" /> 
    </system.web> 
    <system.serviceModel> 
     <services> 
      <service name="WcfTcpTest.Service1" behaviorConfiguration="WcfTcpTest.Service1Behavior"> 
       <host> 
        <baseAddresses> 
         <add baseAddress="http://localhost:8731/Design_Time_Addresses/WcfTcpTest/Service1/" /> 
        </baseAddresses> 
       </host> 
       <endpoint address="" binding="wsHttpBinding" contract="WcfTcpTest.IService1"> 
        <identity> 
         <dns value="localhost"/> 
        </identity> 
       </endpoint> 
       <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
      </service> 
     </services> 
     <behaviors> 
      <serviceBehaviors> 
       <behavior name="WcfTcpTest.Service1Behavior"> 
        <serviceMetadata httpGetEnabled="True"/> 
        <serviceDebug includeExceptionDetailInFaults="True" /> 
       </behavior> 
      </serviceBehaviors> 
     </behaviors> 
    </system.serviceModel> 
</configuration> 

Questo funziona perfettamente, nessun problema a tutti.

ho pensato trasformandolo da HTTP a TCP sarebbe banale: cambiare gli attacchi ai loro equivalenti TCP e rimuovere l'elemento httpGetEnabled serviceMetadata:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.web> 
     <compilation debug="true" /> 
    </system.web> 
    <system.serviceModel> 
     <services> 
      <service name="WcfTcpTest.Service1" behaviorConfiguration="WcfTcpTest.Service1Behavior"> 
       <host> 
        <baseAddresses> 
         <add baseAddress="net.tcp://localhost:1337/Service1/" /> 
        </baseAddresses> 
       </host> 
       <endpoint address="" binding="netTcpBinding" contract="WcfTcpTest.IService1"> 
        <identity> 
         <dns value="localhost"/> 
        </identity> 
       </endpoint> 
       <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/> 
      </service> 
     </services> 
     <behaviors> 
      <serviceBehaviors> 
       <behavior name="WcfTcpTest.Service1Behavior"> 
        <serviceDebug includeExceptionDetailInFaults="True" /> 
       </behavior> 
      </serviceBehaviors> 
     </behaviors> 
    </system.serviceModel> 
</configuration> 

Ma quando ho eseguito questo ottengo questo errore nel servizio WCF Host:

System.InvalidOperationException: Impossibile trovare il nome del contratto 'IMetadataExchange' nell'elenco dei contratti implementati dal servizio Servizio1. Aggiungere un ServiceMetadataBehavior al file di configurazione o al ServiceHost direttamente per abilitare il supporto per questo contratto.

Ho la sensazione che non è possibile inviare metadati tramite TCP, ma questo è il motivo per cui esiste un'opzione mexTcpBinding?

risposta

20

Bene, se si desidera avere metadati - TCP o HTTP - è ancora necessario includere il comportamento serviceMetadata!

<behaviors> 
    <serviceBehaviors> 
     <behavior name="WcfTcpTest.Service1Behavior"> 
      <serviceDebug includeExceptionDetailInFaults="True" /> 
      <serviceMetadata /> 
     </behavior> 
    </serviceBehaviors> 
</behaviors> 

Certo, non si può avere un "httpGetEnabled" su di esso - ma il comportamento stesso deve essere presente al fine di consentire lo scambio di metadati (e quindi la IMetadataExchange del contratto).

+0

Grazie! Questo è stato. Non penso che la configurazione di WCF sia stata progettata proprio in quel momento. App.config è un file di configurazione, ho assunto che quando un elemento di configurazione è stato rimosso significa semplicemente "Non imposto esplicitamente alcuna configurazione" e non "Disattiva questa funzionalità". Un modo migliore sarebbe questo: Dai

+1

@David: beh, questa è un'opzione che si potrebbe discutere a lungo. WCF usa solo l'approccio "se non è lì, non è attivo". Una volta che lo sai, va bene e ha molto senso (non devi metterlo lì e impostare active = false per disabilitarlo - basta lasciarlo fuori) –