手动为 WCF 服务创建服务代理

为 Windows Communication Foundation (WCF) 服务创建客户端服务代理的最简单方法是使用 WsUtil 工具在 服务模型 层,如 创建客户端 主题中所述。 但是,如有必要,还可以手动创建服务代理。 此 API 包含用于创建服务代理的 WsCreateServiceProxy 函数,以及用于设置与 WCF 互操作所需的属性的结构、枚举等。

WCF 提供了许多标准绑定,每个绑定都针对特定的使用方案。 尝试连接到的服务使用哪个绑定,进而确定需要自定义哪些通道属性,以便服务代理与服务通信。

为 WCF 的 WSHttpBinding 创建服务代理

WSHttpBinding 适用于主线 Internet Web 服务方案。 它使用更新的 SOAP 版本 1.2 和 WS-Addressing 版本 1.0,并通过公共 HTTP 和 HTTPS 传输启用各种安全设置。 对于) 而言,WWSAPI 没有 WSHttpBinding (或任何 WCF 标准绑定的等效项,但由于其默认 SOAP 版本、WS-Addressing版本和编码格式与 WSHttpBinding 中的版本匹配,因此为使用 WSHttpBinding 的服务创建服务代理非常简单。 例如,若要创建一个服务代理来与没有安全性的 WSHttpBinding 终结点通信,只需使用以下代码片段 (变量声明,) 省略堆和错误创建。 请注意,在对 WsCreateServiceProxy 函数的调用中未指定通道属性或安全说明。

// Create the proxy

hr = WsCreateServiceProxy(
        WS_CHANNEL_TYPE_REQUEST, 
        WS_HTTP_CHANNEL_BINDING, 
        NULL, // security description
        NULL, // proxy properties
        0, // proxy property count
        NULL, // channel properties
        0, // channel property count
        &proxy, 
        error);

函数创建服务代理,并在上述) 函数调用中的 serviceProxy 参数 (&代理中返回指向该服务代理的指针。

为 WCF 的 BasicHttpBinding 创建服务代理

但是,为使用 BasicHttpBinding 绑定的 WCF 服务手动创建服务代理时,必须设置通道的 SOAP 版本和WS-Addressing属性。 这是因为 WWSAPI 默认为 SOAP 版本 1.2,WS-Addressing 1.0。 另一方面,WCF 的 BasicHttpBinding 使用 SOAP 版本 1.1,没有 WS-Addressing。

若要设置通道的 SOAP 版本和WS-Addrssing属性,请声明 WS_CHANNEL_PROPERTY 结构的数组来保存通道属性和相关信息。

WS_CHANNEL_PROPERTY channelProperties[4]; // Array to hold up to 4 channel properties

ULONG channelPropertyCount = 0; // Count of properties set
 
WS_ENVELOPE_VERSION soapVersion = WS_ENVELOPE_VERSION_SOAP_1_1; // Set required SOAP version
channelProperties[channelPropertyCount].id = WS_CHANNEL_PROPERTY_ENVELOPE_VERSION; // Type of first channel property
channelProperties[channelPropertyCount].value = &soapVersion; // Address of the SOAP version value
channelProperties[channelPropertyCount].valueSize = sizeof(soapVersion); // Size of the value
channelPropertyCount++; // Increment property count
 
WS_ADDRESSING_VERSION addressingVersion = WS_ADDRESSING_VERSION_TRANSPORT; // Set required WS-Addressing value
channelProperties[channelPropertyCount].id = WS_CHANNEL_PROPERTY_ADDRESSING_VERSION; // Type of second channel property
channelProperties[channelPropertyCount].value = &addressingVersion ; // Address of the WS-Addressing value
channelProperties[channelPropertyCount].valueSize = sizeof(addressingVersion ); // Size of the value
channelPropertyCount++; // Increment property count
 
// add more channel properties here

然后将通道属性数组 (channelProperties) ,并将 channelPropertyCount) 的属性 (计数传递给 WsCreateServiceProxy (或 WsCreateChannel (如果使用的是通道层) )。

// Create the proxy

hr = WsCreateServiceProxy(
        WS_CHANNEL_TYPE_REQUEST, 
        WS_HTTP_CHANNEL_BINDING, 
        NULL, // security description
        NULL, // proxy properties
        0, // proxy property count
        channelProperties, // channel properties
        channelPropertyCount, // channel property count
        &proxy, 
        error);

声明用于保存属性的数组在 WsCreateServiceProxy 中复制,因此,可以在调用 函数后立即释放属性数组的内存。 此外,如果从堆栈 (分配内存(如上面的代码片段) ),也可以在调用后立即从 函数返回。

其他绑定

此外,WWSAPI 还提供用于创建服务代理的机制,以使用其他绑定(例如 NetTcpBinding 和 WSFederationHttpBinding)与 WCF 服务进行通信。 其中许多绑定需要设置其他通道属性,例如安全描述符。 有关说明如何使用其他绑定的示例,请参阅 Windows Web Services 示例部分,特别是 TCP 通道层示例HTTP 通道层示例和安全 通道层示例 子节。