Board index » delphi » ESOAPDomConvertError

ESOAPDomConvertError


2007-03-28 04:07:36 PM
delphi53
Hi
How do I prevent this area?
---------------------------
Error
---------------------------
ESOAPDomConvertError Must enable multiref output for objects when serializing
a graph of objects - (Pushpin)
---------------------------
OK
---------------------------
TIA
Graham Harris
 
 

Re:ESOAPDomConvertError

Hello Graham,
Meant "How do I prevent this error?"
Graham Harris
Quote
Hi

How do I prevent this area?

---------------------------
Error
---------------------------
ESOAPDomConvertError Must enable multiref output for objects when
serializing
a graph of objects - (Pushpin)
---------------------------
OK
---------------------------
TIA

Graham Harris

 

Re:ESOAPDomConvertError

Hello,
Quote
>ESOAPDomConvertError Must enable multiref output for objects when
>serializing
>a graph of objects - (Pushpin)
If you're in non-RPC mode - which would be the case for MapPoint as it is a
document style service - you must ensure that the converter does not
encounter the same object more than once while serializing a request. Since
document style does not support multiref, the logic stores the address of
each object as it is being serialized, then proceeds to serialize the
members(class) or elements(array) of the object. If somewhere there's a
cycle and we detect that we're about to serialize an object that we've
already serialized, that exception is fired.
The type in this case was a Pushpin. If you're sending more than one
Pushpin, you will want to make sure that there's a unique object for each,
even if they have the same property values.
NOTE: it is also possible to run into this in cases where you
(a) Use the component to serialize an object to XML and forget to call
'ResetMultiRef'. The next call might encounter the same address already in
the object list although it is clearly not a problem as we're in a new call.
(b) Have custom TRemotable-derived types that allocate and free objects in
ObjectToSOAP [or methods invoked from]. In that case the objects were
distinct but allocated the same memory address by the memory manager.
In the case where you're just invoking a WebService using types generated by
the importer, (a) and (b) don't apply.
Let me know if the above does not help and we'll investigate some more.
Cheers,
Bruneau.
 

Re:ESOAPDomConvertError

Hello Bruneau,
Quote
Have custom TRemotable-derived types that allocate and free
objects in ObjectToSOAP [or methods invoked from]. In that case the
objects were distinct but allocated the same memory address by the
memory manager.

In the case where you're just invoking a WebService using types
generated by the importer, (a) and (b) don't apply.

I have derived the following from a Imported object:
TMapPointPushPin = class(PushPin)
private
FIconID: TStockIcon;
FCustomIconName: WideString;
FObjectID: WideString;
function GetIconName(const Value: TStockIcon): WideString;
procedure SetIconID(const Value: TStockIcon);
public
constructor Create; override;
procedure Assign(Pin: TMapPointPushPin);
procedure SetLabel(Value: WideString); overload;
procedure SetLabel(Strings: TStrings); overload;
function AsPushPin(StandardIconDataSource, CustomIconDataSource: WideString;
CustomIcons: TStrings): PushPin;
published
property CustomIconName: WideString read FCustomIconName write FCustomIconName;
property IconID: TStockIcon read FIconID write SetIconID;
property ObjectID: WideString read FObjectID write FObjectID;
end;
I have posted the imported WSDL and the unit the above code is defined in.
Look for the following subject: ESOAPDomConvertError FAO Bruneau
TIA
Graham Harris
 

Re:ESOAPDomConvertError

Hello,
Quote
I have posted the imported WSDL and the unit the above code is defined in.
Look for the following subject: ESOAPDomConvertError FAO Bruneau
I suspect you posted in the binaries section. I will take a peek there...
Cheers,
Bruneau.
 

Re:ESOAPDomConvertError

Hello,
I see that you have a collection of pushpins. I also see that the Get(Index)
member returns the actual object in the collection. I don't see the code
that uses that collection but I can imagine a scenario whereby a given
request could use the same PushPin [i.e. same Index to 'Get'] more than
once. This could result in a case where the following logic catches the same
Pushpin:
AddObjectAsWriting(Instance);
try
{ NOTE: Don't prefix for simple types }
if (IsSimpleClass) then
ObjConvOpts := ObjConvOpts + [ocoDontPrefixNode];
CreateObjectNode(Obj, RootNode, InstNode,
ExtPropName, ElemURI, ObjConvOpts);
finally
RemoveObjectAsWriting(Obj);
end;
Basically before we serialize an object we add to the list by calling
'AddObjectAsWriting'. Then we proceed. We remove the object upon returning.
One way to avoid creating a cycle is to make Get(Index) returns a clone
object.
There's also another danger to Get(Index) returning the object in a
collection. The importer generates code in the destructor of
TRemotable-derive classes that does a deep cleanup - invoking .Free on class
members and arrays of class members. Typically I warn users to watch for
cases where they have cycles in a request/response: unlike the serialization
code, the cleanup logic does not keep track of objects already cleaned;
hence it can result in cyclic calls to .Free. In code that I have that
communicates with RPC services, I often have a routine that unhooks all
cycles before I invoke .Free on the base object.
Could it be that a given request is retrieving the same Pushpin from the
collection. If yes, you will need to clone the Pushpin to ensure that an
object added via AddObjectAsWriting(....) is removed before it is added
again.
Please let me know if I am missing something.
Cheers,
Bruneau.
 

Re:ESOAPDomConvertError

Hey.... wait a minute I just noticed something -
The bug was starring right at me:)
Quote
AddObjectAsWriting(Instance);
try
{... }
finally
RemoveObjectAsWriting(Obj);
end;
The first line above should read "AddObjectAsWriting(Obj);" !!!!!
I'm going to write a testcase that illustrates this bug right away and then
check in the fix
Thank you - somehow we never caught this before.
More later,
Bruneau.
"Jean-Marie Babet" <XXXX@XXXXX.COM>writes
Quote
Hello,

I see that you have a collection of pushpins. I also see that the
Get(Index)
member returns the actual object in the collection. I don't see the code
that uses that collection but I can imagine a scenario whereby a given
request could use the same PushPin [i.e. same Index to 'Get'] more than
once. This could result in a case where the following logic catches the
same
Pushpin:

AddObjectAsWriting(Instance);
try
{ NOTE: Don't prefix for simple types }
if (IsSimpleClass) then
ObjConvOpts := ObjConvOpts +
[ocoDontPrefixNode];
CreateObjectNode(Obj, RootNode, InstNode,
ExtPropName, ElemURI, ObjConvOpts);
finally
RemoveObjectAsWriting(Obj);
end;


Basically before we serialize an object we add to the list by calling
'AddObjectAsWriting'. Then we proceed. We remove the object upon
returning.

One way to avoid creating a cycle is to make Get(Index) returns a clone
object.

There's also another danger to Get(Index) returning the object in a
collection. The importer generates code in the destructor of
TRemotable-derive classes that does a deep cleanup - invoking .Free on
class
members and arrays of class members. Typically I warn users to watch for
cases where they have cycles in a request/response: unlike the
serialization
code, the cleanup logic does not keep track of objects already cleaned;
hence it can result in cyclic calls to .Free. In code that I have that
communicates with RPC services, I often have a routine that unhooks all
cycles before I invoke .Free on the base object.

Could it be that a given request is retrieving the same Pushpin from the
collection. If yes, you will need to clone the Pushpin to ensure that an
object added via AddObjectAsWriting(....) is removed before it is added
again.

Please let me know if I am missing something.

Cheers,

Bruneau.


 

Re:ESOAPDomConvertError

OK, indeed there was a bug in the code whereby we'd add the parent object to
the ObjectWriting list when serializing a class property. However, upon
investigating a little I don't think that is related to the issue you're
seeing. The current bug, it seems, would result in us failing to detect a
cycle if an instance had a property pointing to itself... IOW, I believe the
current logic would still catch cycles but would not have caught all cycles.
More on this later...
Bruneau.
 

Re:ESOAPDomConvertError

Hi Bruneau
I use the method AsArrayOfPushPin which loops through the list of PushPins
and for each pushpin I call the AsPushPin method of TMapPointPushPin
Graham Harris