Ange en slutpunktsadress
All kommunikation med en WCF-tjänst (Windows Communication Foundation) sker via dess slutpunkter. Var ServiceEndpoint och en innehåller en Address, en Bindingoch en Contract. Kontraktet anger vilka åtgärder som är tillgängliga. Bindningen anger hur du kommunicerar med tjänsten och adressen anger var tjänsten ska hittas. Varje slutpunkt måste ha en unik adress. Slutpunktsadressen EndpointAddress representeras av klassen, som innehåller en URI (Uniform Resource Identifier) som representerar adressen för tjänsten, en Identity, som representerar tjänstens säkerhetsidentitet och en samling valfria Headers. De valfria rubrikerna innehåller mer detaljerad adressinformation för att identifiera eller interagera med slutpunkten. Rubriker kan till exempel ange hur ett inkommande meddelande ska bearbetas, var slutpunkten ska skicka ett svarsmeddelande eller vilken instans av en tjänst som ska användas för att bearbeta ett inkommande meddelande från en viss användare när flera instanser är tillgängliga.
Definition av en slutpunktsadress
I WCF modellerar en EndpointAddress slutpunktsreferens (EPR) enligt definitionen i WS-adresseringsstandarden.
Adress-URI:n för de flesta transporter har fyra delar. Den här URI: http://www.fabrikam.com:322/mathservice.svc/secureEndpoint
n har till exempel följande fyra delar:
Schema: http:
Maskin:
www.fabrikam.com
(Valfritt) Port: 322
Sökväg: /mathservice.svc/secureEndpoint
En del av EPR-modellen är att varje slutpunktsreferens kan innehålla några referensparametrar som lägger till extra identifierande information. I WCF modelleras dessa referensparametrar som instanser av AddressHeader klassen.
Slutpunktsadressen för en tjänst kan anges antingen imperativt med hjälp av kod eller deklarativt via konfiguration. Det är vanligtvis inte praktiskt att definiera slutpunkter i kod eftersom bindningar och adresser för en distribuerad tjänst vanligtvis skiljer sig från de som används när tjänsten utvecklas. I allmänhet är det mer praktiskt att definiera tjänstslutpunkter med hjälp av konfiguration i stället för kod. Genom att hålla bindnings- och adressinformationen borta från koden kan de ändras utan att behöva omkompilera och distribuera om programmet. Om inga slutpunkter anges i kod eller i konfigurationen lägger körningen till en standardslutpunkt på varje basadress för varje kontrakt som implementeras av tjänsten.
Det finns två sätt att ange slutpunktsadresser för en tjänst i WCF. Du kan ange en absolut adress för varje slutpunkt som är associerad med tjänsten eller ange en basadress för ServiceHost en tjänst och sedan ange en adress för varje slutpunkt som är associerad med den här tjänsten som är definierad i förhållande till den här basadressen. Du kan använda var och en av dessa procedurer för att ange slutpunktsadresserna för en tjänst i antingen konfiguration eller kod. Om du inte anger någon relativ adress använder tjänsten basadressen. Du kan också ha flera basadresser för en tjänst, men varje tjänst tillåts endast en basadress för varje transport. Om du har flera slutpunkter, som var och en är konfigurerad med en annan bindning, måste deras adresser vara unika. Slutpunkter som använder samma bindning men olika kontrakt kan använda samma adress.
När du är värd för IIS hanterar du inte instansen ServiceHost själv. Basadressen är alltid den adress som anges i .svc-filen för tjänsten när du är värd i IIS. Därför måste du använda relativa slutpunktsadresser för IIS-värdbaserade tjänstslutpunkter. Om du anger en fullständigt kvalificerad slutpunktsadress kan det leda till fel i distributionen av tjänsten. Mer information finns i Distribuera en Internet Information Services-värdbaserad WCF-tjänst.
Definiera slutpunktsadresser i konfigurationen
Om du vill definiera en slutpunkt i en konfigurationsfil använder du slutpunktselementet><.
<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>
Open När metoden anropas (dvs. när värdprogrammet försöker starta tjänsten) söker systemet efter ett <tjänstelement> med ett namnattribut som anger "UE. Samples.HelloService". <Om tjänstelementet> hittas läser systemet in den angivna klassen och skapar slutpunkter med hjälp av de slutpunktsdefinitioner som anges i konfigurationsfilen. Med den här mekanismen kan du läsa in och starta en tjänst med två kodrader samtidigt som du håller bindnings- och adressinformationen borta från koden. Fördelen med den här metoden är att dessa ändringar kan göras utan att programmet behöver kompileras om eller distribueras om.
De valfria rubrikerna deklareras i rubriker><. Följande är ett exempel på de element som används för att ange slutpunkter för en tjänst i en konfigurationsfil som skiljer mellan två rubriker: "Gold"-klienter från http://tempuri1.org/
och "Standard"-klienter från http://tempuri2.org/
. Klienten som anropar den här tjänsten måste ha lämpliga rubriker i sin konfigurationsfil>.<
<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>
Rubriker kan också ställas in på enskilda meddelanden i stället för alla meddelanden på en slutpunkt (som du visade tidigare). Detta görs med hjälp OperationContextScope av för att skapa en ny kontext i ett klientprogram för att lägga till en anpassad rubrik i det utgående meddelandet, enligt följande exempel.
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
Slutpunktsadress i metadata
En slutpunktsadress representeras i WSDL (Web Services Description Language) som ett EPR-element (WS-Addressing EndpointReference
) inuti motsvarande slutpunktselement wsdl:port
. EPR innehåller slutpunktens adress samt eventuella adressegenskaper. Observera att EPR inuti wsdl:port
ersätts soap:Address
enligt följande exempel.
Definiera slutpunktsadresser i kod
En slutpunktsadress kan skapas i kod med EndpointAddress -klassen. Den URI som anges för slutpunktsadressen kan vara en fullständigt kvalificerad sökväg eller en sökväg som är relativ till tjänstens basadress. Följande kod visar hur du skapar en instans av EndpointAddress klassen och lägger till den i den ServiceHost instans som är värd för tjänsten.
I följande exempel visas hur du anger den fullständiga slutpunktsadressen i koden.
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();
}
I följande exempel visas hur du lägger till en relativ adress ("MyService") till tjänstvärdens basadress.
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();
}
Kommentar
Egenskaperna för ServiceDescription i tjänstprogrammet får inte ändras efter metoden på OnOpeningServiceHostBase. Vissa medlemmar, till exempel Credentials egenskapen och AddServiceEndpoint
metoderna på ServiceHostBase och ServiceHost, utlöser ett undantag om de ändras efter den punkten. Andra tillåter att du ändrar dem, men resultatet är odefinierat.
På samma sätt får värdena på klienten ServiceEndpoint inte ändras efter anropet till OnOpening på ChannelFactory. Egenskapen Credentials utlöser ett undantag om det ändras efter den punkten. De andra klientbeskrivningsvärdena kan ändras utan fel, men resultatet är odefinierat.
Oavsett om det gäller tjänsten eller klienten rekommenderar vi att du ändrar beskrivningen innan du anropar Open.
Använda standardslutpunkter
Om inga slutpunkter anges i kod eller konfiguration tillhandahåller körningen standardslutpunkter genom att lägga till en standardslutpunkt på varje basadress för varje tjänstkontrakt som implementeras av tjänsten. Basadressen kan anges i kod eller i konfigurationen, och standardslutpunkterna läggs till när Open anropas på ServiceHost.
Om slutpunkter uttryckligen anges kan standardslutpunkterna fortfarande läggas till genom att anropa AddDefaultEndpoints innan du ServiceHost anropar Open. Mer information om standardslutpunkter, bindningar och beteenden finns i Förenklad konfiguration och förenklad konfiguration för WCF-tjänster.