指定终结点地址
与 Windows Communication Foundation (WCF) 服务的所有通信都是通过服务的终结点发生的。每个 ServiceEndpoint 都包含一个 Address、一个 Binding 和一个 Contract。协定指定可用的操作。绑定指定如何与服务进行通信,而地址指定查找服务的位置。每个终结点都必须具有一个唯一的地址。终结点的地址由 EndpointAddress 类表示,该类包含一个表示服务地址的统一资源定位符 (URI),一个表示服务的安全标识的 Identity 和一个可选的 Headers 集合。可选标头提供用于标识终结点或与终结点交互的更多详细寻址信息。例如,标头可指示如何处理传入消息,终结点应发送答复消息的位置,或在多个实例可用时应使用哪个服务实例处理来自特定用户的传入消息。
终结点地址的定义
在 WCF 中,EndpointAddress 按照 WS-Addressing 标准中的定义建立终结点引用 (EPR) 的模型。
大多数传输的地址 URI 包含四个部分。例如,“http://www.fabrikam.com:322/mathservice.svc/secureEndpoint”这个 URI 具有以下四个部分:
- 方案:http:
- 计算机:www.fabrikam.com
- (可选)端口:322
- 路径:/mathservice.svc/secureEndpoint
作为 EPR 模型的一部分,每个终结点引用都可以包含一些添加额外标识信息的引用参数。在 WCF 中,将这些引用参数建模为 AddressHeader 类的实例。
可以通过使用代码以强制方式或通过配置以声明方式指定服务的终结点地址。在代码中定义终结点通常不可行,因为已部署的服务的绑定和地址通常不同于开发服务时使用的绑定和地址。一般而言,使用配置定义服务终结点比使用代码更为可行。通过将绑定和寻址信息放置在代码之外,可以在更改这些信息之后不必重新编译和重新部署应用程序。
在 WCF 中,有两种指定服务终结点地址的方式。可以为每个与服务关联的终结点指定一个绝对地址,也可以为服务的 ServiceHost 提供一个基址,然后再为每个与此服务关联的终结点指定一个地址(该地址是相对于此基址定义的)。可以在配置或代码中使用这两种过程来为服务指定终结点地址。如果不指定相对地址,则服务会使用基址。也可以为一个服务指定多个基址,但是对于每个传输协议,每个服务只允许有一个基址。如果有多个终结点,则会使用不同的绑定来配置每个终结点,它们的地址必须是唯一的。使用相同绑定但使用不同协定的终结点可以使用相同的地址。
使用 IIS 承载时,您不用自己管理 ServiceHost 实例。在 IIS 中承载时,基址始终为在服务的 .svc 文件中指定的地址。因此,必须对 IIS 承载的服务终结点使用相对终结点地址。提供完全限定的终结点地址会在服务的部署过程中导致错误。有关更多信息,请参见 部署承载于 Internet 信息服务中的 WCF 服务。
在配置中定义终结点地址
若要在配置文件中定义终结点,请使用 <endpoint> 元素。
调用 Open 方法时(即,当主机应用程序尝试启动服务时),系统会查找一个 <service> 元素(其名称属性指定“UE.Samples.HelloWorld”)。如果找到 <service> 元素,则系统加载指定的类,并使用配置文件中提供的终结点定义来创建终结点。此机制允许您将绑定和寻址信息放置在代码之外,而用两行代码来加载和启动服务。此方法的优点是在进行这些更改后不必重新编译或重新部署应用程序。
可选的标头在 <headers> element 中声明。下面是用于在配置文件中指定服务终结点的元素的示例,该配置文件分为两个标头:来自 http://tempuri1.org/ 的“黄金”客户端和来自 http://tempuri2.org/ 的“标准”客户端。调用此服务的客户端必须在其配置文件中具有相应的 <headers> element。
也可以为个别消息而不是终结点上的所有消息(如前面所示)设置标头。可以通过使用 OperationContextScope 在客户端应用程序中创建新的上下文以向传出消息添加自定义标头,完成此操作,如以下示例中所示。
元数据中的终结点地址
终结点地址在 Web 服务描述语言 (WSDL) 中表示为对应终结点的 wsdl:port 元素内的 WS-Addressing EndpointReference (EPR) 元素。EPR 包含终结点的地址以及所有的地址属性。请注意,wsdl:port 内的 EPR 可替换 soap:Address,如下面的示例所示。
在代码中定义终结点地址
在代码中可以使用 EndpointAddress 类创建终结点地址。为终结点地址指定的 URI 可以是完全限定的路径,也可以是相对于服务的基址的路径。下面的代码演示如何创建 EndpointAddress 类的实例,并将其添加到承载服务的 ServiceHost 实例中。
下面的示例演示如何在代码中指定完整的终结点地址。
下面的示例演示将相对地址(“MyService”)添加到服务主机的基址中。
提示
服务应用程序中 ServiceDescription 的属性不能在 ServiceHostBase 上的 OnOpening 方法之后进行修改。如果在该点之后修改某些成员(如 Credentials 属性以及 ServiceHostBase 和 ServiceHost 上的 AddServiceEndpoint 方法),则将引发异常。允许修改其他成员,但结果不可确定。
同样,在调用 ChannelFactory 上的 OnOpening 之后不能在客户端上修改 ServiceEndpoint 值。如果在该点之后修改 Credentials 属性,则该属性将引发异常。可以对其他客户端说明值进行修改而不会出现错误,但结果不可确定。 无论是对于服务还是客户端,建议您在调用 Open 之前修改说明。