powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Добавление поля в прокси-класс через наследника.
7 сообщений из 7, страница 1 из 1
Добавление поля в прокси-класс через наследника.
    #39590240
SOAPProblem
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть WSDL, по которому сгенерированы прокси-классы. Реальный сервер возвращает дополнительное поле, которое отсутствует в WSDL, но которое хотелось бы получать на клиенте. При этом не хотелось бы менять ни WSDL, ни сгенерированные прокси-классы. WSDL обновляется и его нужно периодически заново загружать, поэтому пришлось бы повторять сделанные изменения при каждой загрузке.

Примерный вид сгенерированных прокси-классов:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
ParentClass = class(TRemotable)
end;

UseClass = class(TRemotable)
  FA: ParentClass;
published
  property A: ParentClass Index (IS_REF) read FA write FA;
end;



В отдельном модуле был создан наследник:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
ChildClass = class(ParentClass)
private
  FNewField: TNewField;
public
  constructor Create; override;
  destructor Destroy; override;
published
  property NewField: TNewField Index (IS_REF) read FNewField write FNewField;
end;



Хотелось бы извлекать дополнительное поле следующим образом:

Код: pascal
1.
2.
3.
4.
var
  ServerResult: ChildClass;

ServerResult := (UseClass.A as ChildClass); // Invalid class typecast



и работать с ServerResult.NewField

Возможно ли решить задачу, используя RegisterXSClass, RegisterExternalPropName, ... ?
...
Рейтинг: 0 / 0
Добавление поля в прокси-класс через наследника.
    #39590252
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторРеальный сервер возвращает дополнительное поле, которое отсутствует в WSDL, но которое хотелось бы получать на клиенте
Это разве не нарушение соглашения?

авторВозможно ли решить задачу, используя RegisterXSClass, RegisterExternalPropName
По идее возможно.
Замените регистрацию ParentClass на ChildClass и добавьте регистрацию NewField
...
Рейтинг: 0 / 0
Добавление поля в прокси-класс через наследника.
    #39590282
SOAPProblem
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пробовал разные варианты параметров, но пока ничего не получилось. Примерный неработающий вариант:

Код: pascal
1.
2.
  RemClassRegistry.RegisterXSClass(ChildClass, 'urn://...', 'ParentClass', 'ParentClass');
  RemClassRegistry.RegisterExternalPropName(TypeInfo(ChildClass), 'NewField', '[Namespace="urn://..."]');



Это архитектурная особенность сервиса. Дополнительные поля могут быть разными и разрабатываются разными организациями, которые предоставляют XSD для них. При этом, по идее, при изменении как WSDL, так и XSD, нужно менять код только одного из них. Если бы удалось реализовать идею с наследником, то так бы и было. Сейчас реализован вариант, в котором ParentClass изменён напрямую, но при каждой загрузке WSDL все изменения нужно повторять вручную. Поэтому и возник вопрос, нельзя ли всё-таки сделать это через наследника.
...
Рейтинг: 0 / 0
Добавление поля в прокси-класс через наследника.
    #39590418
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В стандартном фреймворке есть нюанс
Есть код
Код: pascal
1.
2.
3.
4.
5.
6.
TSOAPDomConv.ConvertSOAPToObject
...
      if (NodeClass <> nil) and NodeClass.InheritsFrom(AClass) then
        Obj := TRemotableClass(NodeClass).Create
      else
        Obj := TRemotableClass(AClass).Create;


где
Код: pascal
1.
2.
    GetElementType(ObjNode, NodeURI, NodeTypeName);
    NodeClass := RemTypeRegistry.URIToClass(NodeURI, NodeTypeName, IsScalar);



Если сервер который отдает ответ document/literal стиль, то NodeTypeName = '' из-за чего NodeClass = nil и тогда парсинг идет по ветке
Код: pascal
1.
Obj := TRemotableClass(AClass).Create;

, где AClass есть ParentClass
Если посмотреть в код GetElementType, то увидим, что
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
V := Node.GetAttribute(SSoapType);
if not VarIsNull(V) then
    begin
      S := V;
      if IsPrefixed(S) then
      begin
        TypeName := ExtractLocalName(S);
        Pre := ExtractPrefix(S);
        TypeURI := Node.FindNamespaceURI(Pre);
      end
      else
      begin
        TypeName := S;
        TypeURI := Node.NamespaceURI;
      end;
      Result := True;
    end;


т.е. если сервер отдает ответ в стиле RPC/encoded то у ответа в теге будет аттрибут type, что-то вроде этого
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
<soap:envelope>
    <soap:body>
        <myMethod>
            <x xsi:type="xsd:int">5</x>
            <y xsi:type="xsd:float">5.0</y>
        </myMethod>
    </soap:body>
</soap:envelope>


И тогда можно зарегистрировать реализатор через
Код: pascal
1.
RemClassRegistry.ClassToURI(TSystemWork, SomeUri, SomeType);


Либо договорится с сервером чтобы они клали туда аттрибут type с именем типа, по которому вы будете регистрировать в зависимости от организации
...
Рейтинг: 0 / 0
Добавление поля в прокси-класс через наследника.
    #39590428
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А нет.. я соврал...
ClassToURI - это наоборот, по классу получить URI.

Надо регистрировать через
RegisterXSClass, но опять же это работает только для RPC/encoded
...
Рейтинг: 0 / 0
Добавление поля в прокси-класс через наследника.
    #39590435
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Либо как вариант вы перегружаете SOAPToObject в вашем классе UseClass и уже сами решаете что и как будет использоваться
...
Рейтинг: 0 / 0
Добавление поля в прокси-класс через наследника.
    #39590486
SOAPProblem
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо за советы! Завтра на работе попробую ими воспользоваться.
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Добавление поля в прокси-класс через наследника.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]