Родительские элементы Потомка TRemotable не включены в WSDL, сгенерированный веб-сервисами Дельфи

Я сделал веб-сервисы с Delphi в прошлом, но большинство было довольно просто, который просто взял несколько параметров и возвратил единственное значение клиенту. Новый сервис я работаю над призывами ко мне, чтобы смочь отправить и получить составные типы. Полагайте, что следующие типы определяются в моем коде:

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.

Теперь я также получил следующую функцию, определяемую в интерфейсе для этого веб-сервиса:

function SpecialMethod(request:TSepecialRequest): TSpecialResponse;

В служебном коде я могу легко получить доступ к свойствам родительского класса как Имя пользователя и Пароль, но если мы смотрим на WSDL, который сгенерирован, мы видим, что участники класса TSpecialRequest и TSpecialResponse включены в раздел схемы.

  <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>

Этот фрагмент схемы в WSDL показывает, что TSpecials являются расширениями классов TBase, и все хорошо за исключением того, что описание классов TBase не включено в схему. Я ожидал бы там также быть разделом как это, но он отсутствует:

  <xs:complexType name="TBaseRequest">
    <xs:sequence>
      <xs:element name="Username" type="xs:string"/>
      <xs:element name="Password" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="TBaseResponse">
    <xs:sequence>
      <xs:element name="StatusMessage" type="xs:string"/>
      <xs:element name="StatusCode" type="xs:int"/>
    </xs:sequence>
  </xs:complexType>

Однако этот фрагмент схемы отсутствует в сгенерированном WSDL. Это означает, что любой клиент, пытающийся использовать этот сервис, не сможет правильно генерировать запросы или интерпретировать ответы. Например, если я пытаюсь загрузить geneated WSDL в средство импорта WSDL в Delphi 2009, я получаю следующие классы:

TSpecialRequest = class(TRemotable)
private
  FExtraParam: WideString;
published
  property ExtraParam: WideString read FExtraParam write FExtraParam;
end;

TSpecialResponse = class(TRemotable)
private
  FStatusMessage: WideString;
  FStatusCode: Integer;
published
  property StatusMessag: WideString read FStatusMessage write FStatusMessage;
  property StatusCode: Integer read FStatusCode write FStatusCode;
end;

Результат состоит в том, что клиентский код не может сделать, вещам нравится, устанавливает участников имени пользователя и пароля, которые должны быть частью TSpecialRequest.

У кого-либо есть какая-либо подсказка, почему это происходит или что я могу делать с этим?

1
задан William Leader 4 June 2010 в 15:03
поделиться

1 ответ

Не думаю, что получу ответ, но я нашел обходной путь. Я не очень доволен этим, но это помогает мне решить проблему. Описанного выше симптома можно избежать, используя композицию объектов вместо наследования. Этот код работает так, как ожидалось, но его не так просто использовать. Я полагаю, что хочу придумать некую фабрику сообщений в своей реализации, но это уже не по теме.

Это решение можно проиллюстрировать следующим кодом:

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;
1
ответ дан 3 September 2019 в 00:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: