Consumare un servizio WCF ospitato in un servizio Windows da una soluzione esterna

Ho creato una libreria WCF ospitata in un servizio di Windows utilizzando il seguente walk-through:

http://msdn.microsoft.com/en-us/library/ff649818.aspx

Le winform del consumatore si trovano nella stessa soluzione, che si trova localmente sul mio C: C del mio PC di lavoro.

Il walk-through funziona cioè il pulsante winforms mi dà la risposta corretta.

Se creo una nuova soluzione sul C-Drive con un singolo progetto Windows Form al suo interno, non riesco ad aggiungere un service reference al servizio in esecuzione con questo servizio, ottengo il seguente messaggio:

inserisci la descrizione dell'immagine qui

Il messaggio dettagliato dice quanto segue:

Il prefisso URI non è riconosciuto. I metadati contengono un riferimento che non può essere risolto: ‘net.tcp: // localhost: 8526 / Service1’. Imansible connettersi a net.tcp: // localhost: 8526 / Service1. Il tentativo di connessione è durato per un periodo di 00: 00: 02.0020000. Codice di errore TCP 10061: non è stato ansible stabilire alcuna connessione perché la macchina di destinazione lo ha rifiutato triggersmente 127.0.0.1:8526. Imansible stabilire una connessione perché la macchina di destinazione lo ha rifiutato triggersmente 127.0.0.1:8526 Se il servizio è definito nella soluzione corrente, provare a creare la soluzione e aggiungere nuovamente il riferimento al servizio.

Perché è ansible aggiungere questo riferimento di servizio ok a un progetto all’interno della stessa soluzione del servizio ma non da un progetto in una soluzione diversa?


MODIFICARE

Il mio collega ha riscontrato un errore nell’articolo di MSDN: ho dettagliato la sua ricerca QUI

L’articolo dettagliato passo passo su MSDN termina purtroppo dove diventa interessante, quindi continuiamo qui. Poiché ci sono molte possibilità che possono causare l’errore, ho descritto diverse opzioni (= scencarios che potrebbero causare il problema) di seguito, che dovrebbero aiutare a risolvere i problemi:

1a opzione: prova a specificare

  net.tcp://localhost:8526/Service1/mex 

quando aggiungi il riferimento del servizio al tuo nuovo client, assicurati che il servizio sia installato e in esecuzione prima di farlo.

Spiegazione: Il suffisso “mex” sta per “scambio di metadati” e consente a Visual Studio di scaricare i dettagli del contratto WCF. Questo suffisso viene anche utilizzato nell’esempio walk-through, è stato aggiunto automaticamente (lo vedrai nel campo Indirizzo se riapri il riferimento al servizio aggiunto facendo clic con il pulsante destro del mouse su “Configura servizio-riferimento …”).


Seconda opzione: quello che ho notato quando ho provato il walk-through è che a volte aiuta a fare clic con il pulsante destro del mouse sul riferimento del servizio e selezionare nel menu di controllo “Servizio di aggiornamento-Riferimento”.

Dopo un po ‘ nella systray puoi vedere il messaggio del fumetto “I tuoi servizi sono stati ospitati”. , dopo di che è ansible avviare il client all’interno della stessa soluzione. In questo caso, il servizio è stato temporaneamente creato ma non è distribuito in modo permanente, il che significa che, se si interrompe il debug, viene rimosso. Di conseguenza, non è ansible utilizzare questo servizio da un PC remoto, è solo visibile all’interno della soluzione in Visual Studio. Visual Studio richiama internamente lo strumento

 WcfSvcHost.Exe /Service: /Configuration: 

supportandolo con i giusti parametri per registrare correttamente il servizio (puoi trovare questo strumento nella sottodirectory Common7\IDE Visual Studio, e c’è anche WcfTestClient.Exe disponibile, uno strumento che funge da client, molto utile per eseguire il debug di WCF).

Ad esempio, se hai interrotto il debugging e avvii client.exe da Windows Explorer al di fuori di Visual Studio, non trova il servizio e ottieni esattamente il messaggio di errore che hai descritto nella domanda.

Ci sono due link interessanti su questo argomento in Microsoft: Problema con Metadata Exchange e Publishing Metadata

Si noti che questo è diverso dalla distribuzione come descritto nella terza opzione.


Terza opzione: hai usato InstallUtil per distribuire il servizio? In questo caso può capitare di aver rimosso accidentalmente la sottodirectory [...]/bin/Debug e il servizio non si avvia, perché manca il file .EXE .

Nota: questo può essere evitato se si sta utilizzando un progetto ServiceInstaller , che copia i file binari prima che il servizio sia registrato. Oppure, se si desidera utilizzare InstallUtil per semplicità, è ansible copiare i file binari del servizio in una directory di destinazione (inclusi i file .config e .dlls) prima di registrarlo.


Quarta opzione: se si esegue il servizio su un computer remoto , è necessario specificare il nome host o l’indirizzo IP corretto dell’host anziché localhost , e assicurarsi che il firewall personale (Windows Firewall o 3rd party) non bloccare la porta 8526 (il numero di porta utilizzato nell’esempio). Specificare un’eccezione per consentire a questa porta il traffico in entrata e in uscita.


5a e ultima opzione (UPDATE): conflitto di denominazione – Service1 è il servizio ma anche il nome della class nella libreria Wcf. O qualificare completamente il nome della class che si sta utilizzando dalla libreria WCF nel servizio, ad esempio WcfServiceLibrary1.Service1 o rinominare la class. Whytheq l’ha trovato da solo con un collega e lo ha pubblicato qui .


Altre letture: Dai un’occhiata a questo articolo, che ho trovato di recente: ” WCF: alcuni consigli “. Spiega molto bene la risoluzione di WCF. L’unica modifica che avrei apportato all’esempio di hosting della console è la sostituzione dell’istruzione using con a

 ServiceHost host = new ServiceHost(typeof(Service)); try { host.Open(); Console.WriteLine("WCF Service is ready for requests." + "Press any key to close the service."); Console.WriteLine(); Console.Read(); Console.WriteLine("Closing service..."); } finally { if (host!=null) { host.Close(); host=null; } } 

Se vuoi saperne di più sul motivo, dai un’occhiata a questo articolo: ” Proxy open and close “.

Puoi aggirare questo come segue:

  • Sfoglia l’URL WSDL del servizio e salva il WSDL in un file locale.
  • Quindi apportare le seguenti modifiche al file:
  • Rimuovere il prefisso dello spazio dei nomi dal nome utilizzato per wsdl: binding ie change name = “wb: wsclocks-inboundSoapBinding” per essere name = “wsclocks-inboundSoapBinding”
  • Modificare l’attributo di associazione dell’attributo wsdl: port in modo che corrisponda e rimuovere anche il prefisso dello spazio dei nomi dal valore dell’attributo name, quindi è solo wsclocks-inbound.

Quindi eseguire svcutil / o: Client \ WBServices / noConfig