Specifying an Endpoint Address
2010-01-18 16:09
141 查看
Specifying an Endpoint Address
All communication with a Windows Communication Foundation (WCF) service occurs through its endpoints. Each ServiceEndpoint contains an Address, a Binding, and a Contract. The contract specifies which operations are available. The binding specifies how to communicate with the service, and the address specifies where to find the service. Every endpoint must have a unique address. The endpoint address is represented by the EndpointAddress class, which contains a Uniform Resource Identifier (URI) that represents the address of the service, an Identity, which represents the security identity of the service, and a collection of optional Headers. The optional headers provide more detailed addressing information to identify or interact with the endpoint. For example, headers can indicate how to process an incoming message, where the endpoint should send a reply message, or which instance of a service to use to process an incoming message from a particular user when multiple instances are available.
The address URI for most transports has four parts. For example, this URI, "http://www.fabrikam.com:322/mathservice.svc/secureEndpoint" has the following four parts:
Scheme: http:
Machine: www.fabrikam.com
(optional) Port: 322
Path: /mathservice.svc/secureEndpoint
Part of the EPR model is that each endpoint reference can carry some reference parameters that add extra identifying information. In WCF, these reference parameters are modeled as instances of the AddressHeader class.
The endpoint address for a service can be specified either imperatively by using code or declaratively through configuration. Defining endpoints in code is usually not practical because the bindings and addresses for a deployed service are typically different from those used while the service is being developed. Generally, it is more practical to define service endpoints using configuration rather than code. Keeping the binding and addressing information out of the code allows them to change without having to recompile and redeploy the application.
There are two ways to specify endpoint addresses for a service in WCF. You can specify an absolute address for each endpoint associated with the service or you can provide a base address for the ServiceHost of a service and then specify an address for each endpoint associated with this service that is defined relative to this base address. You can use each of these procedures to specify the endpoint addresses for a service in either configuration or code. If you do not specify a relative address, the service uses the base address. You can also have multiple base addresses for a service, but each service is allowed only one base address for each transport. If you have multiple endpoints, each of which is configured with a different binding, their addresses must be unique. Endpoints that use the same binding but different contracts can use the same address.
When hosting with IIS, you do not manage the ServiceHost instance yourself. The base address is always the address specified in the .svc file for the service when hosting in IIS. So you must use relative endpoint addresses for IIS-hosted service endpoints. Supplying a fully-qualified endpoint address can lead to errors in the deployment of the service. For more information, see Deploying an Internet Information Services-Hosted WCF Service.
Xml
[align=center][/align]Copy Code
When the Open method is called (that is, when the hosting application attempts to start the service), the system looks for a <service> element with a name attribute that specifies "UE.Samples.HelloService". If the <service> element is found, the system loads the specified class and creates endpoints using the endpoint definitions provided in the configuration file. This mechanism allows you to load and start a service with two lines of code while keeping binding and addressing information out of your code. The advantage of this approach is that these changes can be made without having to recompile or redeploy the application.
The optional headers are declared in a <headers> element. The following is an example of the elements used to specify endpoints for a service in a configuration file that distinguishes between two headers: "Gold" clients from http://tempuri1.org/ and "Standard" clients from http://tempuri2.org/. The client calling this service must have the appropriate <headers> element in its configuration file.
Xml
[align=center][/align]Copy Code
Headers can also be set on individual messages instead of all messages on an endpoint (as shown previously). This is done by using OperationContextScope to create a new context in a client application to add a custom header to the outgoing message, as shown in the following example.
C#
[align=center][/align]Copy Code
The following example demonstrates how to specify the full endpoint address in code.
C#
[align=center][/align]Copy Code
The following example demonstrates how to add a relative address ("MyService") to the base address of the service host.
C#
[align=center][/align]Copy Code
Endpoint Creation Overview
All communication with a Windows Communication Foundation (WCF) service occurs through its endpoints. Each ServiceEndpoint contains an Address, a Binding, and a Contract. The contract specifies which operations are available. The binding specifies how to communicate with the service, and the address specifies where to find the service. Every endpoint must have a unique address. The endpoint address is represented by the EndpointAddress class, which contains a Uniform Resource Identifier (URI) that represents the address of the service, an Identity, which represents the security identity of the service, and a collection of optional Headers. The optional headers provide more detailed addressing information to identify or interact with the endpoint. For example, headers can indicate how to process an incoming message, where the endpoint should send a reply message, or which instance of a service to use to process an incoming message from a particular user when multiple instances are available.
Definition of an Endpoint Address
In WCF, an EndpointAddress models an endpoint reference (EPR) as defined in the WS-Addressing standard.The address URI for most transports has four parts. For example, this URI, "http://www.fabrikam.com:322/mathservice.svc/secureEndpoint" has the following four parts:
Scheme: http:
Machine: www.fabrikam.com
(optional) Port: 322
Path: /mathservice.svc/secureEndpoint
Part of the EPR model is that each endpoint reference can carry some reference parameters that add extra identifying information. In WCF, these reference parameters are modeled as instances of the AddressHeader class.
The endpoint address for a service can be specified either imperatively by using code or declaratively through configuration. Defining endpoints in code is usually not practical because the bindings and addresses for a deployed service are typically different from those used while the service is being developed. Generally, it is more practical to define service endpoints using configuration rather than code. Keeping the binding and addressing information out of the code allows them to change without having to recompile and redeploy the application.
There are two ways to specify endpoint addresses for a service in WCF. You can specify an absolute address for each endpoint associated with the service or you can provide a base address for the ServiceHost of a service and then specify an address for each endpoint associated with this service that is defined relative to this base address. You can use each of these procedures to specify the endpoint addresses for a service in either configuration or code. If you do not specify a relative address, the service uses the base address. You can also have multiple base addresses for a service, but each service is allowed only one base address for each transport. If you have multiple endpoints, each of which is configured with a different binding, their addresses must be unique. Endpoints that use the same binding but different contracts can use the same address.
When hosting with IIS, you do not manage the ServiceHost instance yourself. The base address is always the address specified in the .svc file for the service when hosting in IIS. So you must use relative endpoint addresses for IIS-hosted service endpoints. Supplying a fully-qualified endpoint address can lead to errors in the deployment of the service. For more information, see Deploying an Internet Information Services-Hosted WCF Service.
Defining Endpoint Addresses in Configuration
To define an endpoint in a configuration file, use the <endpoint> element.Xml
[align=center][/align]Copy Code
<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>
When the Open method is called (that is, when the hosting application attempts to start the service), the system looks for a <service> element with a name attribute that specifies "UE.Samples.HelloService". If the <service> element is found, the system loads the specified class and creates endpoints using the endpoint definitions provided in the configuration file. This mechanism allows you to load and start a service with two lines of code while keeping binding and addressing information out of your code. The advantage of this approach is that these changes can be made without having to recompile or redeploy the application.
The optional headers are declared in a <headers> element. The following is an example of the elements used to specify endpoints for a service in a configuration file that distinguishes between two headers: "Gold" clients from http://tempuri1.org/ and "Standard" clients from http://tempuri2.org/. The client calling this service must have the appropriate <headers> element in its configuration file.
Xml
[align=center][/align]Copy Code
<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>
Headers can also be set on individual messages instead of all messages on an endpoint (as shown previously). This is done by using OperationContextScope to create a new context in a client application to add a custom header to the outgoing message, as shown in the following example.
C#
[align=center][/align]Copy Code
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(); }
Endpoint Address in Metadata
An endpoint address is represented in Web Services Description Language (WSDL) as a WS-Addressing EndpointReference (EPR) element inside the corresponding endpoint's wsdl:port element. The EPR contains the endpoint's address as well as any address properties. Note that the EPR inside wsdl:port replaces soap:Address as seen in the following example.Defining Endpoint Addresses in Code
An endpoint address can be created in code with the EndpointAddress class. The URI specified for the endpoint address can be a fully-qualified path or a path that is relative to the service's base address. The following code illustrates how to create an instance of the EndpointAddress class and add it to the ServiceHost instance that is hosting the service.The following example demonstrates how to specify the full endpoint address in code.
C#
[align=center][/align]Copy Code
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(); }
The following example demonstrates how to add a relative address ("MyService") to the base address of the service host.
C#
[align=center][/align]Copy Code
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(); }
![]() Note: |
---|
Properties of the ServiceDescription in the service application must not be modified subsequent to the OnOpening method on ServiceHostBase. Some members, such as the Credentials property and the AddServiceEndpoint methods on ServiceHostBase and ServiceHost, throw an exception if modified after that point. Others permit you to modify them, but the result is undefined. Similarly, on the client the ServiceEndpoint values must not be modified after the call to OnOpening on the ChannelFactory. The Credentials property throws an exception if modified after that point. The other client description values can be modified without error, but the result is undefined. Whether for the service or client, it is recommended that you modify the description prior to calling Open. |
![]() Note: |
---|
In Windows7, if the client and the service are on the same machine, the service is running under a UPN account and the client is connecting to the service with the full machine name using 'Negotiate' security mechanism, the call to the service fails with a SecurityNegotiationException ("The target principal name is incorrect"). You can resolve this by either changing the client endpoint address to refer to localhostor specifying the UPN in the request. This is a changed behavior on the Win7 platform as compared to down-level (such as Vista) where the negotiate security mechanism uses Kerberos instead of NTLM. |
See Also
Reference
EndpointAddressConcepts
Service Identity and AuthenticationEndpoint Creation Overview
Other Resources
Hosting of Windows Communication Foundation Services相关文章推荐
- 10 Specifying an Endpoint Configurator Class
- System.Net.Sockets.SocketException: An address incompatible with the requested protocol was used.
- 转载《Adding a Second IP Address to an Existing Network Adapter on Linux》
- An introduction to Linux Virtual Address Space Layout
- Endpoint--Address
- docker集群初始化manager节点报错:could not choose an IP address to advertise
- mappedBy reference an unknown target entity property: com.sq.entity.Address.tt_user in com.sq.entit
- svnmanager:You entered an invalid email address.
- NGINX学习笔记——Choosing an Outgoing IP Address
- tomcat启动不了——Error initializing endpoint——java.net.BindException: Address already in use: JVM_Bind <n
- The host file--map a name to an IP address
- Bean property 'address' is not readable or has an invalid getter method: Does the return type of th
- 第一次使用Genymotion遇到的问题:for an unknown reson,VirtualBox DHCP has not assigned an IP address to virtual
- Error initializing endpoint java.net.BindException: Address already in use: JVM_Bind:8080
- [Non-original]OS X How do I unset an IP address set with ifconfig?
- This email address is not valid for use as an Apple ID.
- WCF 异常:无法打开安全通道,因为与远程终结点的安全协商已失败。这可能是由于用于创建通道的 EndpointAddress 中不存在 EndpointIdentity ....