TWSDLHTMLPublish генерирует неправильный wsdl?

#delphi #soap #wsdl

Вопрос:

я использую Delphi 10.4.2 и пишу приложение сервера SOAP. Для создания WSDL я использую компонент TWSDLHTMLPublish, сброшенный на моего потомка TWebModule. У меня возникли проблемы с отображением атрибутов и необязательных элементов в файле wsdl.

Мой интерфейс определяет объекты следующим образом:

 // TRemotable Property Index constants.
// Quelle: http://www.codenewsfast.com/cnf/article/0/permalink.art-ng1920q2865
const
  IS_OPTN = $0001;   // This element is optional (minOccurs=0); Don't serialize it if its value was not explicitly set
  IS_UNBD = $0002;   // This array element is unbounded (The runtime serializes dyn arrays as either collection or unbounded elements)
  IS_NLBL = $0004;   // This element is nillable (xsi:nillable=true)
  IS_UNQL = $0008;   // This element is unqualified (see http://www.w3schools.com/schema/el_schema.asp) Runtime defaults to qualified otherwise
  IS_ATTR = $0010;   // This property is an attribute (otherwise the runtime serializes it as an element)
  IS_TEXT = $0020;   // This property is text (typically of the parent element) (see http://www.w3schools.com/schema/schema_complex_text.asp)
  IS_ANY  = $0040;   // This property represents an xsd:any element (not really used by runtime)
  IS_REF  = $0080;   // This property is a ref (i.e. ref=QName) element (see http://www.w3schools.com/schema/el_element.asp)
  IS_QUAL = $0100;   // This attribute is qualified (the runtime defaults to unqualified otherwise)

type
  OrderDirection    = (OrderNONE, OrderASC, OrderDESC);
  ProjektOrderField = (pofNONE, pofID, pofNummer, pofStatus);
  ProjektStatus     = (psAll, psAnfrage, psAuftrag, psAbgeschlossen);

ProjektFilterType = class(TRemotable)
  private
    FStatus               : ProjektStatus;
    FStatus_specified     : Boolean;
    FOrderField           : ProjektOrderField;
    FOrderField_specified : Boolean;
    FOrderDir             : OrderDirection;
    FOrderDir_specified   : Boolean;
    FTestAttribut         : string;
    Procedure SetStatus          (Index: Integer; const Value: ProjektStatus);
    Procedure SetOrderDir        (Index: Integer; const Value: OrderDirection);
    Procedure SetOrderField      (Index: Integer; const Value: ProjektOrderField);
  public
    Function Status_Specified    (Index: Integer) : Boolean;
    Function OrderDir_Specified  (Index: Integer) : Boolean;
    Function OrderField_Specified(Index: Integer) : Boolean;
  published
    property TestAttribut : string             Index (IS_UNQL OR IS_ATTR)  read FTestAttribut  write FTestAttribut;
    property Status       : ProjektStatus      Index (IS_UNQL OR IS_OPTN)  read FStatus        write SetStatus       stored Status_specified;
    property OrderField   : ProjektOrderField  Index (IS_UNQL OR IS_OPTN)  read FOrderField    write SetOrderField   stored OrderField_specified;
    property OrderDir     : OrderDirection     Index (IS_UNQL OR IS_OPTN)  read FOrderDir      write SetOrderDir     stored OrderDir_specified;
  end;
 
 // ================================================================================
{$REGION '   ==================== ProjektFilterType ===================='}
Function ProjektFilterType.Status_Specified(Index: Integer) : Boolean;
begin
  Result := FStatus_Specified;
end;

Function ProjektFilterType.OrderDir_Specified(Index: Integer) : Boolean;
begin
  Result := FOrderDir_Specified;
end;

Function ProjektFilterType.OrderField_Specified(Index: Integer) : Boolean;
begin
  Result := FOrderField_Specified;
end;

Procedure ProjektFilterType.SetStatus(Index: Integer; const Value: ProjektStatus);
begin
  FStatus           := Value;
  FStatus_Specified := true;
end;

Procedure ProjektFilterType.SetOrderDir(Index: Integer; const Value: OrderDirection);
begin
  FOrderDir           := Value;
  FOrderDir_Specified := true;
end;

Procedure ProjektFilterType.SetOrderField(Index: Integer; const Value: ProjektOrderField);
begin
  FOrderField           := Value;
  FOrderField_Specified := true;
end;
{$ENDREGION}
// ================================================================================
 

выходной файл wsdl выглядит следующим образом:

 <xs:complexType name="ProjektFilterType">
  <sequence xmlns="http://www.w3.org/2001/XMLSchema">
    <xs:element name="TestAttribut" type="xs:string"/>
    <xs:element name="Status" type="ns1:ProjektStatus"/>
    <xs:element name="OrderField" type="ns1:ProjektOrderField"/>
    <xs:element name="OrderDir" type="ns1:OrderDirection"/>
  </sequence>
</xs:complexType>
 

Проблема: IS_ATTR не работает вообще — вывод xs:элемент вместо xs.атрибут, и в элементах отсутствуют атрибуты minOccurs=»0″ и maxOccurs=»1″.

что я делаю не так? Какие-либо атрибуты RTTI, которые я должен определить, кроме Индекса свойств?

Ответ №1:

хорошо, я нашел это в источниках Embarcaqdero:

ПРИМЕЧАНИЕ: В настоящее время параметры сериализации предназначены только для использования Клиентом. т. е. Они используются импортером WSDL при создании типов из WSDL. Серверы не должны регистрировать какие — либо типы с этими параметрами, так как логика публикации WSDL будет игнорировать все параметры сериализации. IOW, эти флаги предназначены для адаптации привязки языка к конструкциям, которые нелегко сопоставить с собственным типом, например, в примере массива с атрибутом. Серверам не нужно прибегать ни к одному из этих флагов, так как все потребности сервера могут быть сопоставлены с SOAP без использования классов владельцев.

Поэтому я сгенерирую свой wdsl вручную и использую wsdl-импортер для создания интерфейсного блока. Я надеялся, что будет более простой способ (для меня: -)), но я могу с этим смириться…