Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
&引用;属性未声明";Delphi生成的EWS SOAP请求中出错_Delphi_Soap_Delphi Xe2_Exchangewebservices - Fatal编程技术网

&引用;属性未声明";Delphi生成的EWS SOAP请求中出错

&引用;属性未声明";Delphi生成的EWS SOAP请求中出错,delphi,soap,delphi-xe2,exchangewebservices,Delphi,Soap,Delphi Xe2,Exchangewebservices,这是在从Exchange Server检索WDSL后生成的调用ResolveNames的工作示例代码: <?xml version="1.0"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:mes="h

这是在从Exchange Server检索WDSL后生成的调用ResolveNames的工作示例代码:

<?xml version="1.0"?>
<soapenv:Envelope 
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
  xmlns:typ="http://schemas.microsoft.com/exchange/services/2006/types" 
  xmlns:mes="http://schemas.microsoft.com/exchange/services/2006/messages">
<soapenv:Header><typ:RequestServerVersion Version="Exchange2010"/></soapenv:Header>
<soapenv:Body>
  <mes:ResolveNames ReturnFullContactData="1" SearchScope="ActiveDirectoryContacts">
    <mes:UnresolvedEntry>deve</mes:UnresolvedEntry>
  </mes:ResolveNames>
</soapenv:Body>
</soapenv:Envelope>
它产生:

<?xml version="1.0"?>
<SOAP-ENV:Envelope 
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body xmlns:NS1="http://schemas.microsoft.com/exchange/services/2006/types">
  <ResolveNames xmlns="http://schemas.microsoft.com/exchange/services/2006/messages" ReturnFullContactData="true" NS1:SearchScope="ActiveDirectoryContacts">
    <UnresolvedEntry>deve</UnresolvedEntry>
  </ResolveNames>
  <MailboxCulture xsi:nil="true"/>
  <ExchangeImpersonation xsi:nil="true"/>
  <NS1:RequestServerVersion Version="Exchange2010"/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

德维
我得到的错误:

请求架构验证失败:未声明“”属性

SearchScope是messages.xsd中定义的属性:

<!-- ResolveNames request -->

<xs:complexType name="ResolveNamesType">
    <xs:complexContent>
        <xs:extension base="m:BaseRequestType">
            <xs:sequence>
                <xs:element name="ParentFolderIds" type="t:NonEmptyArrayOfBaseFolderIdsType" minOccurs="0"/>
                <xs:element name="UnresolvedEntry" type="t:NonEmptyStringType"/>
            </xs:sequence>
            <xs:attribute name="ReturnFullContactData" type="xs:boolean" use="required"/>
            <xs:attribute name="SearchScope" type="t:ResolveNamesSearchScopeType" default="ActiveDirectoryContacts"/>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

<xs:element name="ResolveNames" type="m:ResolveNamesType"/>

对于in-types.xsd:

<!-- ResolveNames request -->

<xs:simpleType name="ResolveNamesSearchScopeType">
  <xs:restriction base="xs:string">
    <xs:enumeration value="ActiveDirectory"/>
    <xs:enumeration value="ActiveDirectoryContacts"/>
    <xs:enumeration value="Contacts"/>
    <xs:enumeration value="ContactsActiveDirectory"/>
  </xs:restriction>
</xs:simpleType>

我认为NS1:SearchScope=“ActiveDirectoryContacts”不正确,但保留NS1:out会产生相同的错误。
可能是将类型和消息的Exchange xmlns规范推迟到SOAP-ENV:Body中是导致错误的原因?
另外,NS1:RequestServerVersion=“Exchange2010”不在SOAP\u ENV:头中 看起来可疑

我已经看过了,但没法让它工作

基本上我的问题是:
如何在生成的代码中移动标记或xmlns属性,直到它工作为止,而不必自己构造整个SOAP?
如果这是不可能的,什么方法是最好的,这样我仍然可以从导入的类型库中获益?(比如?)

谢谢

Jan

我决定不尝试修复特定的XML标记,而是完全控制即将发布的SOAP内容:
我只是在TStringStream中构建XML,然后在HTTPRIO.beforecute中,我将TStringStream内容放入SOAPStream中。
安装后,我可以导入WDSL,然后“手动”生成并测试所需的SOAP调用。完成这些后,我将它们移动到Delphi代码中。
这给了我一个优势,即仍然可以访问WDSL生成的代码来解析结果(无需深入研究返回的XML)

这是代码,它显示了旧方法(BtnConnectClick)和新方法(BtnAlternateClick)

unitutestews;
接口
使用
Winapi.Windows、Winapi.Messages、System.SysUtils、System.Variants、System.Classes、Vcl.Graphics、,
Vcl.控件、Vcl.窗体、Vcl.对话框、Vcl.StdCtrls、Vcl.ComCtrls、Vcl.ExtCtrls、TypInfo、WinAPI.WinInet、,
Soap.Rio、Soap.InvokeRegistry、Soap.SOAPHTTPClient、Soap.SOAPHTTPTrans、,
服务{=从WDSL生成的文件};
类型
TFrmTestEWS=类(TForm)
HTTPRIO:THTTPRIO;
小组1:TPanel;
MmoLog:TMemo;
电视:TTreeView;
结果:TMemo;
BTN连接:t按钮;
b可选:t按钮;
备忘录1:TMemo;
标签1:TLabel;
过程httpriobeforecute(const MethodName:string;
SOAPRequest:TStream);
过程HTTPRIOAfterExecute(const MethodName:string;
SOAPResponse:TStream);
过程BtnConnectClick(发送方:TObject);
程序HTTPRIO1HTTPWebNode1BeforePost(常量HTTPReqResp:THTTPReqResp;
数据:指针);
程序BtnAlternateClick(发送方:TObject);
过程表单创建(发送方:ToObject);
销毁程序表(发送方:TObject);
私有的
FSoapData:TStringStream;
程序Res(Msg:String);
程序初始化APDATA;
程序和数据;
公众的
结束;
变量
FrmTestEWS:TFrmTestEWS;
实施
{$R*.dfm}
过程TFrmTestEWS.BtnConnectClick(发送方:TObject);
变量
lESB:ExchangeServicePortType;
lResNames:解析名称;
lReqVersion:RequestServerVersion;
lResResult:ResolveNamesResponse;
lServerVer:ServerVersionInfo;
开始
lServerVer:=ServerVersionInfo.Create;
lResNames:=ResolveNames.Create;
lReqVersion:=RequestServerVersion.Create;
lResResult:=ResolveNamesResponse.Create;
尝试
尝试
// 1. 安装程序
(*替换为alternate,请参见BTNALTernate单击
lunsolved:=“deve”;
有爱尔兰人的名字吗
开始
ReturnFullContactData:=真;
SearchScope:=ResolveNamesSearchScopeType.ActiveDirectoryContacts;//作用域枚举已启用!
ParentFolderId:=nil;
unsolvedEntry:=lUnresolved;
结束;
lReqVersion.Version:=ExchangeVersionType.Exchange2010;
*)
// 2. 执行
lESB:=(HttpIO作为ExchangeServicePortType);
lESB.ResolveNames(lResNames,
无,//模拟
无,//MailboxCulture
lReqVersion,
勒斯雷苏尔,
lServerVer);
// 3. 报告
结果:清晰;
Res('服务器版本:');
用lserverdo
开始
Res('MajorVersion:'+IntToStr(MajorVersion));
Res('MinorVersion:'+IntToStr(MinorVersion));
Res('MajorBuildNumber:'+IntToStr(MajorBuildNumber));
Res('MinorBuildNumber:'+IntToStr(MinorBuildNumber));
Res(‘版本:’+版本);
结束;
//[剪下与本例无关的其余代码]
除了
在E上:异常结果。文本:=E.消息;
结束;
最后
// 4. 清理
lResResult.Free;
lServerVer.Free;
lReqVersion.Free;
lResNames.free;
LESB:=零;
结束;
结束;
过程TFrmTestEWS.FormCreate(发送方:TObject);
开始
FSoapData:=TStringStream.Create(“”,TEncoding.UTF8);
FSoapData.Position:=0;
结束;
程序TFrmTestEWS.FormDestroy(发送方:TObject);
开始
免费的;
结束;
过程TFrmTestEWS.HTTPRIOAfterExecute(const MethodName:string;
SOAPResponse:TStream);
变量
TS:TStringStream;
S:字符串;
开始
S:=MmoLog.Text+#13#10#13#10+'响应:'+#13#10#10;
TS:=TStringStream.Create;
TS.位置:=长度(S);
SOAPResponse.位置:=0;
TS.CopyFrom(SOAPResponse,SOAPResponse.Size);
TS.位置:=0;
MmoLog.Lines.LoadFromStream(TS);
<!-- ResolveNames request -->

<xs:simpleType name="ResolveNamesSearchScopeType">
  <xs:restriction base="xs:string">
    <xs:enumeration value="ActiveDirectory"/>
    <xs:enumeration value="ActiveDirectoryContacts"/>
    <xs:enumeration value="Contacts"/>
    <xs:enumeration value="ContactsActiveDirectory"/>
  </xs:restriction>
</xs:simpleType>
unit uTestEWS;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, Vcl.ExtCtrls,TypInfo, WinAPI.WinInet,
  Soap.Rio, Soap.InvokeRegistry, Soap.SOAPHTTPClient, Soap.SOAPHTTPTrans,
  services { = The file generated from the WDSL };

type
  TFrmTestEWS = class(TForm)
    HTTPRIO: THTTPRIO;
    Panel1: TPanel;
    MmoLog: TMemo;
    TV: TTreeView;
    MmoResult: TMemo;
    BtnConnect: TButton;
    BtnAlternate: TButton;
    Memo1: TMemo;
    Label1: TLabel;
    procedure HTTPRIOBeforeExecute(const MethodName: string;
      SOAPRequest: TStream);
    procedure HTTPRIOAfterExecute(const MethodName: string;
      SOAPResponse: TStream);
    procedure BtnConnectClick(Sender: TObject);
    procedure HTTPRIO1HTTPWebNode1BeforePost(const HTTPReqResp: THTTPReqResp;
      Data: Pointer);
    procedure BtnAlternateClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FSoapData: TStringStream;
    procedure Res(Msg: String);
    procedure InitializeSoapData;
    procedure FinalizeSoapData;
  public
  end;

var
  FrmTestEWS: TFrmTestEWS;

implementation

{$R *.dfm}

procedure TFrmTestEWS.BtnConnectClick(Sender: TObject);
var
   lESB        : ExchangeServicePortType;
   lResNames   : ResolveNames;
   lReqVersion : RequestServerVersion;
   lResResult  : ResolveNamesResponse;
   lServerVer  : ServerVersionInfo;
begin
   lServerVer  := ServerVersionInfo.Create;
   lResNames   := ResolveNames.Create;
   lReqVersion := RequestServerVersion.Create;
   lResResult  := ResolveNamesResponse.Create;
   try
      try
         // 1. Setup
(* Replaced by alternate, see BtnAlternateClick
         lUnresolved := 'deve';
         with lResNames do
         begin
            ReturnFullContactData := true;
            SearchScope           := ResolveNamesSearchScopeType.ActiveDirectoryContacts;  // Scoped enums is on!
            ParentFolderIds       := nil;
            UnresolvedEntry       := lUnresolved;
         end;
         lReqVersion.Version := ExchangeVersionType.Exchange2010;
*)
         // 2. Execute
         lESB := (HTTPRIO as ExchangeServicePortType);
         lESB.ResolveNames(lResNames,
                           nil,              // Impersonation
                           nil,              // MailboxCulture
                           lReqVersion,
                           lResResult,
                           lServerVer);
         // 3. Report
         MmoResult.Clear;
         Res('Server version:');
         with lServerVer do
         begin
            Res('  MajorVersion: ' + IntToStr(MajorVersion));
            Res('  MinorVersion: ' + IntToStr(MinorVersion));
            Res('  MajorBuildNumber: ' + IntToStr(MajorBuildNumber));
            Res('  MinorBuildNumber: ' + IntToStr(MinorBuildNumber));
            Res('  Version: ' + Version);
         end;
         // [ snip rest of code not relevant for this example]
      except
         on E:Exception do MmoResult.Text := E.Message;
      end;
   finally
      // 4. Clean up
      lResResult.Free;
      lServerVer.Free;
      lReqVersion.Free;
      lResNames.free;
      LESB := nil;
   end;
end;

procedure TFrmTestEWS.FormCreate(Sender: TObject);
begin
   FSoapData := TStringStream.Create('',TEncoding.UTF8);
   FSoapData.Position := 0;
end;

procedure TFrmTestEWS.FormDestroy(Sender: TObject);
begin
  FSoapData.Free;
end;

procedure TFrmTestEWS.HTTPRIOAfterExecute(const MethodName: string;
  SOAPResponse: TStream);
var
   TS: TStringStream;
   S : String;
begin
   S := MmoLog.Text + #13#10#13#10 + 'Response:' + #13#10#13#10;
   TS := TStringStream.Create(S);
   TS.Position := Length(S);
   SOAPResponse.Position := 0;
   TS.CopyFrom(SOAPResponse,SOAPResponse.Size);
   TS.Position := 0;
   MmoLog.Lines.LoadFromStream(TS);
   TS.Free;
end;

procedure TFrmTestEWS.HTTPRIOBeforeExecute(const MethodName: string;
  SOAPRequest: TStream);
begin
   // 1. Alternate approach
   SOAPRequest.Position := 0;
   FSoapData.Position := 0;
   SOAPRequest.CopyFrom(FSoapData,FSoapData.Size);
   SOAPRequest.Size := FSoapData.Size;
   // 2. Logging
   MmoLog.Clear;
   MmoLog.Lines.Add('Request:' + #13#10#13#10);
   FSoapData.Position := 0;
   MmoLog.Lines.LoadFromStream(FSoapData);
end;

procedure TFrmTestEWS.InitializeSoapData;
begin
   FSoapData.Clear;
   FSoapData.WriteString('<soapenv:Envelope');
   FSoapData.WriteString('  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"');
   FSoapData.WriteString('  xmlns:typ="http://schemas.microsoft.com/exchange/services/2006/types"');
   FSoapData.WriteString('  xmlns:mes="http://schemas.microsoft.com/exchange/services/2006/messages">');
   FSoapData.WriteString('<soapenv:Header><typ:RequestServerVersion Version="Exchange2010"/></soapenv:Header>');
   FSoapData.WriteString('<soapenv:Body>');
end;

procedure TFrmTestEWS.FinalizeSoapData;
begin
   FSoapData.WriteString('</soapenv:Body>');
   FSoapData.WriteString('</soapenv:Envelope>');
end;

procedure TFrmTestEWS.BtnAlternateClick(Sender: TObject);
begin
   InitializeSoapData;
   FSoapData.WriteString('  <mes:ResolveNames ReturnFullContactData="1" SearchScope="ActiveDirectoryContacts">');
   FSoapData.WriteString('    <mes:UnresolvedEntry>deve</mes:UnresolvedEntry>');
   FSoapData.WriteString('  </mes:ResolveNames>');
   FinalizeSoapData;
   // Pick up from first attempt 'execute': 
   BtnConnectClick(Sender);
end;

procedure TFrmTestEWS.HTTPRIO1HTTPWebNode1BeforePost(
  const HTTPReqResp: THTTPReqResp; Data: Pointer);
const
   CONTENT_HEADER_EX2010 = 'Content-Type: text/xml; charset=utf-8';
begin
   // http://forum.delphi-treff.de/archive/index.php/t-31817.html
   // Need to exchange the Content-Type Header, because Exchange 2010 expects
   // 'Content-Type: text/xml; charset=utf-8' instead of
   // 'Content-Type: text/xml; charset="utf-8"' which is RFC conform and used by XE2
   HttpAddRequestHeaders(Data, PChar(CONTENT_HEADER_EX2010), Length(CONTENT_HEADER_EX2010), HTTP_ADDREQ_FLAG_REPLACE);
end;

procedure TFrmTestEWS.Res(Msg: String);
begin
   MmoResult.Lines.Add(Msg);
end;

end.