Web services delphi web服务生成的WSDL中不包括可旋转的子代父成员

Web services delphi web服务生成的WSDL中不包括可旋转的子代父成员,web-services,delphi,soap,wsdl,Web Services,Delphi,Soap,Wsdl,我以前使用Delphi创建过Web服务,但大多数都非常简单,只需要几个参数并向客户端返回一个值。我正在处理的一项新服务要求我能够发送和接收复杂类型的电话。考虑在我的代码中定义的以下类型: TBaseRequest = Class(TRemotable) private FUsername: string; FPassword: string; published Property Username: String read FUsername write FUse

我以前使用Delphi创建过Web服务,但大多数都非常简单,只需要几个参数并向客户端返回一个值。我正在处理的一项新服务要求我能够发送和接收复杂类型的电话。考虑在我的代码中定义的以下类型:

TBaseRequest = Class(TRemotable)
  private
    FUsername: string;
    FPassword: string;
  published
    Property Username: String read FUsername write FUsername;
    Property Password: String read FPassword write FPassword;
End;

TBaseResponse = Class(TRemotable)
  private
    FStatusMessage: string;
    FStatusCode: integer;
  published
    Property StatusMessage: string read FStatusMessage write FStatusMessage;
    Property StatusCode: integer read FStatusCode write FStatusCode;
End;

TSepecialRequest = class(TBaseRequest)
private
  FExtraParam: string;
published
  Property ExtraParam: String read FExtraParam write FExtraParam;
end;

TSpecialResponse = class(TBaseResponse)
private
  FExtraResult: string;
published
  Property ExtraResult: String read FExtraResultwrite FExtraResult;
end;
所有这些类都是使用RemClassRegistry.RegisterXSClass注册的

现在,我还在该Web服务的接口中定义了以下函数:

function SpecialMethod(request:TSepecialRequest): TSpecialResponse;
在服务代码中,我可以很容易地访问父类属性,如Username和Password,但是如果我们查看生成的WSDL,就会发现TSpecialRequest和TSpecialResponse类成员包含在schema部分中

  <xs:complexType name="TSpecialRequest">
    <xs:complexContent>
      <xs:extension base="TBaseRequest">
        <xs:sequence>
          <xs:element name="ExtraParam" type="xs:string"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="TSpecialResponse">
    <xs:complexContent>
      <xs:extension base="TBaseResponse">
        <xs:sequence>
          <xs:element name="ExtraResult" type="xs:string"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
结果是,客户端代码无法执行诸如设置用户名和密码成员之类的操作,而这些成员应该是TSSpecialRequest的一部分


有人知道为什么会发生这种情况,或者我能做些什么吗?

我想我不会得到答案,但我已经找到了解决办法。我对它不是很满意,但它让我通过了这个问题。通过使用对象组合而不是继承,可以避免上述症状。此代码的功能与预期相同,但使用起来不太简单。我想我会想在我的实现中提出某种消息工厂,但这偏离了主题

此解决方案可通过以下代码进行说明:

TBaseRequest = Class(TRemotable)
  private
    FUsername: string;
    FPassword: string;
  published
    Property Username: String read FUsername write FUsername;
    Property Password: String read FPassword write FPassword;
end;

TSepecialRequest = class(TRemotable)
private
  FExtraParam: string;
  FBaseRequest: TBaseRequest;
published
  Property ExtraParam: String read FExtraParam write FExtraParam;
  Property BaseRequest: TBaseRequest read FBaseRequest write FBaseRequest;
end;

Delphi只为web服务接口中直接引用的类生成模式。理想情况下,它应该将基类包含回TRemotable,但事实并非如此

但是,我发现,如果在参数列表中向带有基类的接口添加一个伪方法,Delphi将生成缺少的定义。例如:

procedure BaseClasses(BaseRequest: TBaseRequest; BaseResponse: TBaseResponse); stdcall;
这绝对是一种黑客行为,必须公开这样的方法有点烦人,但它确实完成了您想要完成的任务


我知道这个响应对您来说有点晚了,但可能对以后的其他人有用。

如何使用Delphi IDE从Delphi类源代码创建WSDL?到目前为止,我还没有看到Delphi 2009 Enterprise实现这一点的方法(也许我应该把它变成一个新的SO问题:)这是一个离题的问题,应该是一个新问题,但基本上,当您创建一个SOAP服务器应用程序项目时,它将添加一个数据模块,其中包含一个TWSDLHTMLPublish组件。该组件通过注册的接口和远程类,并添加和生成WSDL。要访问WSDL,必须将项目的已编译DLL加载到ISAPI web服务器(如IIS)中,然后使用URL(如),您将看到一个HTML页面,该页面描述服务和到生成的WSDL的链接。结果:WSDL基于delphi代码中定义的类。如果QC服务器启动,您可以在我的工作中的其他位置找到相关的错误报告,我们遇到了相同(或至少非常类似)的问题:在Tokyo 10.2中从WSDL文件生成时遇到了相同的问题,而在Rio 10.3中这样做是可行的。我们不确定是否启用或禁用了不同的选项,但是。。。由于时间不够,我们未能追查差额。
TBaseRequest = Class(TRemotable)
  private
    FUsername: string;
    FPassword: string;
  published
    Property Username: String read FUsername write FUsername;
    Property Password: String read FPassword write FPassword;
end;

TSepecialRequest = class(TRemotable)
private
  FExtraParam: string;
  FBaseRequest: TBaseRequest;
published
  Property ExtraParam: String read FExtraParam write FExtraParam;
  Property BaseRequest: TBaseRequest read FBaseRequest write FBaseRequest;
end;
procedure BaseClasses(BaseRequest: TBaseRequest; BaseResponse: TBaseResponse); stdcall;