Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Tutte le comunicazioni con un servizio Windows Communication Foundation (WCF) vengono eseguite tramite gli endpoint. Ognuno ServiceEndpoint contiene un Addressoggetto , un Bindingoggetto e un oggetto Contract. Il contratto specifica le operazioni disponibili. Il binding specifica come comunicare con il servizio, e l'indirizzo specifica dove trovare il servizio. Ogni endpoint deve avere un indirizzo univoco. L'indirizzo dell'endpoint è rappresentato dalla classe EndpointAddress, che contiene un Identificatore Uniforme di Risorsa (URI) che rappresenta l'indirizzo del servizio, un Identity, che rappresenta l'identità di sicurezza del servizio, e una raccolta di elementi facoltativi Headers. Le intestazioni facoltative forniscono informazioni di indirizzamento più dettagliate per identificare o interagire con l'endpoint. Ad esempio, le intestazioni possono indicare come elaborare un messaggio in arrivo, dove l'endpoint deve inviare un messaggio di risposta o quale istanza di un servizio usare per elaborare un messaggio in ingresso da un determinato utente quando sono disponibili più istanze.
Definizione di un indirizzo endpoint
In WCF, modella un EndpointAddress riferimento dell'endpoint (EPR) come definito nello standard WS-Addressing.
L'URI dell'indirizzo per la maggior parte dei trasporti ha quattro parti. Ad esempio, questo URI ha http://www.fabrikam.com:322/mathservice.svc/secureEndpoint le quattro parti seguenti:
Schema: http:
Macchina:
www.fabrikam.com(Facoltativo) Porta: 322
Percorso: /mathservice.svc/secureEndpoint
Parte del modello EPR è che ogni riferimento all'endpoint può contenere alcuni parametri di riferimento che aggiungono informazioni di identificazione aggiuntive. In WCF questi parametri di riferimento vengono modellati come istanze della AddressHeader classe .
L'indirizzo dell'endpoint per un servizio può essere specificato in modo imperativo usando il codice o in modo dichiarativo tramite la configurazione. La definizione degli endpoint nel codice in genere non è pratica perché le associazioni e gli indirizzi per un servizio distribuito sono in genere diversi da quelli usati durante lo sviluppo del servizio. In genere, è più pratico definire gli endpoint di servizio usando la configurazione anziché il codice. Mantenere le informazioni di associazione e indirizzamento separate dal codice consente di modificarle senza dover ricompilare e ridistribuire l'applicazione. Se non viene specificato alcun endpoint nel codice o nella configurazione, il runtime aggiunge un endpoint predefinito per ogni indirizzo di base per ogni contratto implementato dal servizio.
Esistono due modi per specificare gli indirizzi endpoint per un servizio in WCF. È possibile specificare un indirizzo assoluto per ogni endpoint associato al servizio oppure specificare un indirizzo di base per l'oggetto ServiceHost di un servizio e quindi specificare un indirizzo per ogni endpoint associato a questo servizio definito in relazione a questo indirizzo di base. È possibile usare ognuna di queste procedure per specificare gli indirizzi endpoint per un servizio nella configurazione o nel codice. Se non si specifica un indirizzo relativo, il servizio usa l'indirizzo di base. È anche possibile avere più indirizzi di base per un servizio, ma ogni servizio è consentito un solo indirizzo di base per ogni trasporto. Se sono presenti più endpoint, ognuno dei quali è configurato con un'associazione diversa, gli indirizzi devono essere univoci. Gli endpoint che utilizzano la stessa associazione ma hanno contratti diversi possono utilizzare lo stesso indirizzo.
Quando si ospita con IIS, non si gestisce l'istanza ServiceHost manualmente. L'indirizzo di base è sempre l'indirizzo specificato nel file con estensione svc per il servizio durante l'hosting in IIS. È quindi necessario usare gli indirizzi endpoint relativi per gli endpoint di servizio ospitati da IIS. Fornire un indirizzo endpoint completamente qualificato può causare errori nella distribuzione del servizio. Per altre informazioni, vedere Distribuzione di informazioni Internet Services-Hosted servizio WCF.
Definizione degli indirizzi endpoint nella configurazione
Per definire un endpoint in un file di configurazione, usare l'elemento <endpoint> .
<configuration>
<system.serviceModel>
<services>
<service name="UE.Samples.HelloService"
behaviorConfiguration="HelloServiceBehavior">
<endpoint address="/Address1"
binding="basicHttpBinding"
contract="UE.Samples.IHello"/>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="HelloServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Quando viene chiamato il Open metodo, ovvero quando l'applicazione host tenta di avviare il servizio, il sistema cerca un elemento <service> con un attributo name che specifica "UE.Samples.HelloService". Se viene trovato l'elemento <del servizio> , il sistema carica la classe specificata e crea gli endpoint usando le definizioni di endpoint fornite nel file di configurazione. Questo meccanismo consente di caricare e avviare un servizio con due righe di codice, mantenendo separati dal codice i dati di associazione e indirizzamento. Il vantaggio di questo approccio è che queste modifiche possono essere apportate senza dover ricompilare o ridistribuire l'applicazione.
Le intestazioni facoltative sono dichiarate all'interno di <headers>. Di seguito è riportato un esempio degli elementi usati per specificare gli endpoint per un servizio in un file di configurazione che distingue tra due intestazioni: client "Gold" da http://tempuri1.org/ e client "Standard" da http://tempuri2.org/. Il client che chiama questo servizio deve avere le appropriate <intestazioni> nel file di configurazione.
<configuration>
<system.serviceModel>
<services>
<service name="UE.Samples.HelloService"
behaviorConfiguration="HelloServiceBehavior">
<endpoint address="/Address1"
binding="basicHttpBinding"
contract="UE.Samples.IHello">
<headers>
<Member xmlns="http://tempuri1.org/">Gold</Member>
</headers>
</endpoint>
<endpoint address="/Address2"
binding="basicHttpBinding"
contract="UE.Samples.IHello">
<headers>
<Member xmlns="http://tempuri2.org/">Silver</Member>
</headers>
</endpoint>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="HelloServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Le intestazioni possono essere impostate anche su singoli messaggi anziché su tutti i messaggi su un endpoint (come illustrato in precedenza). Questa operazione viene eseguita usando OperationContextScope per creare un nuovo contesto in un'applicazione client per aggiungere un'intestazione personalizzata al messaggio in uscita, come illustrato nell'esempio seguente.
SampleServiceClient wcfClient = new SampleServiceClient(new InstanceContext(this));
try
{
using (OperationContextScope scope = new OperationContextScope(wcfClient.InnerChannel))
{
MessageHeader header
= MessageHeader.CreateHeader(
"Service-Bound-CustomHeader",
"http://Microsoft.WCF.Documentation",
"Custom Happy Value."
);
OperationContext.Current.OutgoingMessageHeaders.Add(header);
// Making calls.
Console.WriteLine("Enter the greeting to send: ");
string greeting = Console.ReadLine();
//Console.ReadLine();
header = MessageHeader.CreateHeader(
"Service-Bound-OneWayHeader",
"http://Microsoft.WCF.Documentation",
"Different Happy Value."
);
OperationContext.Current.OutgoingMessageHeaders.Add(header);
// One-way
wcfClient.Push(greeting);
this.wait.WaitOne();
// Done with service.
wcfClient.Close();
Console.WriteLine("Done!");
Console.ReadLine();
}
}
catch (TimeoutException timeProblem)
{
Console.WriteLine("The service operation timed out. " + timeProblem.Message);
Console.ReadLine();
wcfClient.Abort();
}
catch (CommunicationException commProblem)
{
Console.WriteLine("There was a communication problem. " + commProblem.Message);
Console.ReadLine();
wcfClient.Abort();
}
Dim wcfClient As New SampleServiceClient(New InstanceContext(Me))
Try
Using scope As New OperationContextScope(wcfClient.InnerChannel)
Dim header As MessageHeader = MessageHeader.CreateHeader("Service-Bound-CustomHeader", _
"http://Microsoft.WCF.Documentation", "Custom Happy Value.")
OperationContext.Current.OutgoingMessageHeaders.Add(header)
' Making calls.
Console.WriteLine("Enter the greeting to send: ")
Dim greeting As String = Console.ReadLine()
'Console.ReadLine();
header = MessageHeader.CreateHeader("Service-Bound-OneWayHeader", _
"http://Microsoft.WCF.Documentation", "Different Happy Value.")
OperationContext.Current.OutgoingMessageHeaders.Add(header)
' One-way
wcfClient.Push(greeting)
Me.wait.WaitOne()
' Done with service.
wcfClient.Close()
Console.WriteLine("Done!")
Console.ReadLine()
End Using
Catch timeProblem As TimeoutException
Console.WriteLine("The service operation timed out. " & timeProblem.Message)
Console.ReadLine()
wcfClient.Abort()
Catch commProblem As CommunicationException
Console.WriteLine("There was a communication problem. " & commProblem.Message)
Console.ReadLine()
wcfClient.Abort()
End Try
Indirizzo degli endpoint nei metadati
Un indirizzo endpoint è rappresentato in Web Services Description Language (WSDL) come elemento WS-Addressing EndpointReference (EPR) all'interno dell'elemento dell'endpoint wsdl:port corrispondente. L'EPR contiene l'indirizzo dell'endpoint e qualsiasi proprietà dell'indirizzo. Si noti che l'EPR all'interno wsdl:port sostituisce soap:Address come illustrato nell'esempio seguente.
Definizione degli indirizzi endpoint nel codice
È possibile creare un indirizzo endpoint nel codice con la EndpointAddress classe . L'URI specificato per l'indirizzo dell'endpoint può essere un percorso completo o un percorso relativo all'indirizzo di base del servizio. Il codice seguente illustra come creare un'istanza della EndpointAddress classe e aggiungerla all'istanza ServiceHost che ospita il servizio.
Nell'esempio seguente viene illustrato come specificare l'indirizzo endpoint completo nel codice.
Uri baseAddress = new Uri("http://localhost:8000/HelloService");
string address = "http://localhost:8000/HelloService/MyService";
using (ServiceHost serviceHost = new ServiceHost(typeof(HelloService), baseAddress))
{
serviceHost.AddServiceEndpoint(typeof(IHello), new BasicHttpBinding(), address);
serviceHost.Open();
Console.WriteLine("Press <enter> to terminate service");
Console.ReadLine();
serviceHost.Close();
}
Nell'esempio seguente viene illustrato come aggiungere un indirizzo relativo ("MyService") all'indirizzo di base dell'host del servizio.
Uri baseAddress = new Uri("http://localhost:8000/HelloService");
using (ServiceHost serviceHost = new ServiceHost(typeof(HelloService), baseAddress))
{
serviceHost.AddServiceEndpoint(typeof(IHello), new BasicHttpBinding(), "MyService");
serviceHost.Open();
Console.WriteLine("Press <enter> to terminate service");
Console.ReadLine();
serviceHost.Close();
}
Annotazioni
Le proprietà di ServiceDescription nell'applicazione di servizio non devono essere modificate successivamente al OnOpening metodo in ServiceHostBase. Alcuni membri, ad esempio la Credentials proprietà e i AddServiceEndpoint metodi in ServiceHostBase e ServiceHost, generano un'eccezione se modificati dopo tale punto. Altri consentono di modificarli, ma il risultato non è definito.
Analogamente, i valori ServiceEndpoint sul client non devono essere modificati dopo la chiamata a OnOpening su ChannelFactory. La Credentials proprietà genera un'eccezione se viene modificata dopo tale punto. Gli altri valori di descrizione client possono essere modificati senza errori, ma il risultato non è definito.
Sia per il servizio che per il client, è consigliabile modificare la descrizione prima di chiamare Open.
Uso degli endpoint predefiniti
Se nel codice o nella configurazione non sono specificati endpoint, il runtime fornisce endpoint predefiniti aggiungendo un endpoint predefinito in ogni indirizzo di base per ogni contratto di servizio implementato dal servizio. L'indirizzo di base può essere specificato nel codice o nella configurazione e gli endpoint predefiniti vengono aggiunti quando Open viene chiamato su ServiceHost.
Se gli endpoint vengono forniti in modo esplicito, gli endpoint predefiniti possono comunque essere aggiunti chiamando AddDefaultEndpoints su ServiceHost prima di chiamare Open. Per altre informazioni su endpoint, associazioni e comportamenti predefiniti, vedere Configurazione semplificata e configurazione semplificata per i servizi WCF.