用Delphi交换Web服务

用Delphi交换Web服务,delphi,soap,exchangewebservices,Delphi,Soap,Exchangewebservices,我想使用Delphi XE6创建一个客户端应用程序 我将THttpRio组件与wsdl一起使用。如何设置用户凭据?在其他语言中,THttpRio组件的等价物有一个Credentials属性()。 但是Delphi组件中缺少这一点 身份验证机制(除了模拟)不是ews wsdl的一部分。它是SOAP层固有的 清单1: procedure TForm1.Button1Click( Sender: TObject); var lESB : ExchangeServicePortTyp

我想使用Delphi XE6创建一个客户端应用程序

我将THttpRio组件与wsdl一起使用。如何设置用户凭据?在其他语言中,THttpRio组件的等价物有一个Credentials属性()。 但是Delphi组件中缺少这一点

身份验证机制(除了模拟)不是ews wsdl的一部分。它是SOAP层固有的

清单1:

procedure TForm1.Button1Click( Sender: TObject);
var
   lESB        : ExchangeServicePortType;
   request       : GetServiceConfiguration;
   Impersonation : ExchangeImpersonation;
   RequestVersion: RequestServerVersion;
   MailboxCulture1: MailboxCulture;
   GetServiceConfigurationResult: GetServiceConfigurationResponse;
   ServerVersion : ServerVersionInfo;
begin
lESB := HTTPRIO1 as ExchangeServicePortType;
request         := GetServiceConfiguration.Create;
request.RequestedConfiguration := ArrayOfServiceConfigurationType.Create( 'UnifiedMessagingConfiguration');
Impersonation   := ExchangeImpersonation.Create;
RequestVersion  := RequestServerVersion.Create;
MailboxCulture1 := MailboxCulture.Create;
GetServiceConfigurationResult:= GetServiceConfigurationResponse.Create;
ServerVersion                := ServerVersionInfo.Create;
try
lESB.GetServiceConfiguration(
  request, Impersonation, RequestVersion, MailboxCulture1,
  GetServiceConfigurationResult, ServerVersion)
finally
  request.Free;
  Impersonation.Free;
  RequestVersion.Free;
  MailboxCulture1.Free;
  GetServiceConfigurationResult.Free;
  ServerVersion.Free
  end
end;
上面的清单1显示了一些到目前为止我已经尝试过的示例代码。该函数的目的是获取有关服务器的版本信息。HTTPRIO1是一个具有默认属性的THTTPRIO组件,并连接到EWS的标准wsdl。这不起作用,因为未设置用户凭据


如何设置用户凭据?

经过多次尝试和错误,这就是我提出的解决方案

(1) 认证 如果使用THTTPRio组件,则可以从通过代理服务器建立internet连接的角度,使用THHPRio的HTTPWebNode属性的用户名/密码对来标识用户的凭据

如果使用THTTPReqResp组件,则该组件直接拥有相同的用户名/密码属性

如果使用TIDWTTP,则需要使用与代理相关的属性

如果要使用当前登录组件的凭据,并将密码显式传递到组件上,可以通过将THTTPRio和THTTPReqResp组件的用户名和密码属性留空来实现。代理信息将自动从系统注册表中提取。然而,HTTP是不同的。此组件需要显式设置代理配置,包括internet用户的凭据

(2) 用于EWS Soap事务的组件是什么? 我无法让标准soap解决方案THTTPRio组件正常工作。问题是THTTPRio组件没有生成正确的请求信封形状。在没有详细说明的情况下,会出现许多问题,例如本应放在主体中的元素,会出现在标题中,以及模式冲突。如果您可以让它(基于已发布的wsdl的THTTPRio)工作(但我对此表示怀疑),那么值得注意的是,需要对wsdl进行调整以包括服务节点。出于安全原因,Microsoft故意排除了服务节点,但这是正确操作Delphi soap向导所必需的

如果您的应用程序位于防火墙后面,并且必须与代理服务器协商,那么开发基于TIdHTTP的解决方案是不可能的

最简单也是最好的解决方案是使用THTTPReqResp组件。你甚至不需要这个wisdl。您必须设计自己的xml请求信封,但有了Microsoft优秀的文档,显示了简单的信封,这项任务很容易完成

(3) 关于使用THTTPReqResp访问EWS
  • EWS使用UTF-8,因此设置UseUTF8InHeader:=True
  • Set InvokeOptions=[soIgnoreInvalidCerts,SOAUTOCHECKACCESSSPOINTVIAUDI]
  • 根据需要将URL设置为服务服务器URL
  • 将SoapAction设置为
    http://schemas.microsoft.com/exchange/services/2006/messages
  • 根据需要设置用户名和密码,或保留为空以使用登录用户的凭据
  • EWS使用soap 1.1,而不是1.2,因此将WNOSAP12从WebNodeOptions中排除
  • 利用MSDN在线。这是一个极好的资源,有很多例子
  • (4) 关于构建XML文档。 Soap信封是遵循特定发布格式的XML文档,其中嵌入了您的请求数据。如何构建这些信封

    这里有两种可能的方法对我很有效:

  • 使用模板软件设计模式。例如,我使用的组件与TPageProducer非常相似。源代码是您的基本模板,您可以使用标记替换来实现所需的结果。我的PageProducer版本可以定义可选片段,或者在一个模板中标记重复n次(每次迭代使用不同的数据)的片段
  • 使用XSLT。这是最简单的解决办法。它几乎是无代码的
  • 这里有两种可能的方法,您可以使用,但我建议不要使用。这并不是因为它们不起作用,而是因为这些技术太笨拙,需要太多的编码:

  • 将文档逐部分手动构造为字符串(或使用字符串生成器)
  • 使用标准XML接口(IXMLNode等)逐部分构建文档,然后输出结果

  • 我从未在Delphi中使用过它,我最终制作了一个中介.NET DLL,您可以很容易地使用它。我强烈建议您使用Indy组件来使用EWS wsdl,而不是使用HttpRIO。@RBA您可以添加一些详细信息(可能作为完整答案)吗?THttpRIO没有基于印地的嵌入式更换部件。Indy(TIdHTTP)可用于下载基于web的WSDL资源,但这无助于解决实际的互操作问题。如果
    THTTPRIO.HTTPWebNode
    THTTPReqResp
    )属性中有
    用户名
    /
    密码
    ,或者我遗漏了什么内容,那么您是如何导入WSDL的呢?