Passing more than one parameter via clientdataset in d2007 with soap is
problem.
Here example in standard application
ADOConnection - ADODataSet - DataSetProviver - ClientDataSet
ADODataSet have SQL query with two parameters and I fetch that parameters in
ClientDataSet and put values and that works fine.
When I make SOAP Server application (WAD) and Client application, if I put
more than one parameters in SQL in ADODataSet I can not fetch params in
ClientDataSet in Client app
Example:
Server (SOAP) app: ADOConnection - ADODataSet - DataSetProviver
Cleint app: SoapConnection - ClientDataSet
If I have ONLY ONE param in SQL query in server (SOAP) app than all work
fine.
More than one param in SQL i got "Invalid argument" when I try to fetch
params in ClientDataSet on Client app
Anyone can help?
The problem you mentioned sounds fairly related to another one we addressed
a while ago:. See
http://dn.codegear.com/article/28514#VARARRAY
Interestingly, in that particular case, the ONE parameter case would fail
but all others would work. I wonder if we somehow regressed this. There's
always been a problem with serializing Variants that contains arrays because
when there's only one element in the array the serialization logic cannot
distinguish between a Variant with a simple value or a Variant with an array
that contains only one element. We introduced a special attribute to handle
this case.
I'm going to ask someone to investigate this and see if we can reproduce the
problem. I'll relay our findings.
Cheers,
Bruneau.
I made some little hack and take OPToSOAPDomConv.pas from d2006 and replace
one on d2007 and thing works in runtime, still on right click on
clientdataset I can not fetch params (invalid arguments), but if I put
params manualy in clientdataset I can pass value over soap to dataset and it
works. So try to find bug in OPToSOAPDomConv.pas.
I try to analize code but is too much and I have no time for tracing bug,
but seems that you forgot something in OPToSOAPDomConv.pas
I find that you have some conditions about widestrings and may be there is a
problem?
So I will be greatfull if someone send me right copy of OPToSOAPDomConv.pas
for d2007 and the rest of dependeces..
Thanks
"Jean-Marie Babet" <bba...@borland.com> wrote in message
news:471f...@newsgroups.borland.com...
In OPToSOAPDomConv.pas replace function
function TSOAPDomConv.ReadVarArrayDim(...)
because in d2007 is used "varIndex" and is not working properly, so old
function works fine
This is not smart and permanent sollution but helps for now, I still hope on
an fixed version of OPToSOAPDomConv.pas
Replace with this one from d2006
function TSOAPDomConv.ReadVarArrayDim(Node: IXMLNode; IsVarVArray: Boolean;
VT: TVarType): Variant;
var
Count, I: Integer;
SoapTypeInfo: PTypeInfo;0
ChildNode: IXMLNode;
TypeURI, TypeName: InvString;
begin
{ Get count of ntElement children node }
Count := ntElementChildCount(Node);
if Count = 0 then
begin
Result := NULL;
Exit;
end;
{
Also, we could use the TVarType to (re)create a Variant of the
original array type; Using VarVariant, however, is more
resilient; and as long as no one cracks the Variant open - i.e.
casts to TVarData and starts accessing members directly - we're safe.
Sure hopes no one does that!!
}
Result := VarArrayCreate([0, Count -1], VarVariant);
for I := 0 to Node.ChildNodes.Count -1 do
begin
ChildNode := Node.ChildNodes[I];
{ Skip non-valid nodes }
if ChildNode.NodeType <> ntElement then
continue;
IsVarVArray := IsNodeAVarArray(ChildNode, VT);
if IsVarVarray or (ntElementChildCount(ChildNode) > 1) then
begin
Result[I] := ReadVarArrayDim(ChildNode, IsVarVArray, VT);
end else
begin
if not NodeIsNULL(ChildNode) then
begin
GetElementType(ChildNode, TypeURI, TypeName);
SoapTypeInfo := RemTypeRegistry.XSDToTypeInfo(TypeURI, TypeName);
if SoapTypeInfo = nil then
SoapTypeInfo := TypeInfo(System.WideString);
{ Handle 'dateTime' }
if IsXMLDateTimeTypeInfo(SoapTypeInfo)
{(SoapTypeInfo.Kind = tkClass) and
(GetTypeData(SoapTypeInfo).ClassType = TXSDateTime)} then
begin
Result[I] := XMLTimeToDateTime(ChildNode.Text);
end else
Result[I] := TypeTranslator.CastSoapToVariant(SoapTypeInfo,
ChildNode.Text);
end else
Result[I] := NULL;
end;
end;
end;
Here is in deign time error (Invalid argument on Right Click on
ClientDataSet on Fetch params):
[2001D76F]{rtl100.bpl } Variants.TranslateResult (Line 576,
"sys\variants.pas" + 10) + $1C
[2001D80C]{rtl100.bpl } Variants.TranslateResult (Line 582,
"sys\variants.pas" + 16) + $23
[2001D824]{rtl100.bpl } Variants.VarResultCheck (Line 587,
"sys\variants.pas" + 1) + $0
[2002538C]{rtl100.bpl } Variants.VarArrayAsPSafeArray (Line 4383,
"sys\variants.pas" + 2) + $5
[200253EF]{rtl100.bpl } Variants.VarArrayHighBound (Line 4404,
"sys\variants.pas" + 1) + $4
[203D5637]{dsnap100.bpl} DBClient.UnpackParams (Line 803, "DBClient.pas" +
7) + $18
[203D697C]{dsnap100.bpl} DBClient.TCustomClientDataSet.FetchParams (Line
1182, "DBClient.pas" + 2) + $43
[227B400D]{dclmid100.bpl} LMidReg.TClientDataSetEditor.ExecuteVerb (Line
202, "LMidReg.pas" + 9) + $2
[211D904E]{vcldesigner100.bpl} VCLSurface.TVclDesignSurface.ComponentVerb
(Line 2473, "vclsurface.pas" + 3) + $B
[2012F2C3]{vcl100.bpl } Menus.TMenuItem.Click (Line 1877, "Menus.pas" + 14)
+ $8
[201307EB]{vcl100.bpl } Menus.TMenu.DispatchCommand (Line 2602, "Menus.pas"
+ 5) + $2
[2013194A]{vcl100.bpl } Menus.TPopupList.WndProc (Line 3392, "Menus.pas" +
4) + $E
[20131899]{vcl100.bpl } Menus.TPopupList.MainWndProc (Line 3373,
"Menus.pas" + 2) + $5
[20040DD4]{rtl100.bpl } Classes.StdWndProc (Line 11583,
"common\Classes.pas" + 8) + $0
[201611EC]{vcl100.bpl } Forms.TApplication.ProcessMessage (Line 8102,
"Forms.pas" + 23) + $1
[20161226]{vcl100.bpl } Forms.TApplication.HandleMessage (Line 8121,
"Forms.pas" + 1) + $4
[20161537]{vcl100.bpl } Forms.TApplication.Run (Line 8219, "Forms.pas" +
20) + $3
[0042298E]{bds.exe } bds.bds (Line 196, "" + 7) + $7
"Jean-Marie Babet" <bba...@borland.com> wrote in message
news:471f...@newsgroups.borland.com...
> I made some little hack and take OPToSOAPDomConv.pas from d2006 and
replace
> one on d2007 and thing works in runtime, still on right click on
> clientdataset I can not fetch params (invalid arguments), but if I put
> params manualy in clientdataset I can pass value over soap to dataset and
it
> works. So try to find bug in OPToSOAPDomConv.pas.
OK, so it seems that we regressed from D2006 to D2007. It's normal that it
fails when your right-click because that's design-time code that's prebuilt
by Borland. You can't rebuild that. But the fact that the runtime works when
you replace your runtime file with the one from D2006 is telling.
Would you mind emailing me the original (D2007) version and the D2006 one
that you used to resolve the problem at runtime? I have so many versions of
OpToSOAPDomConvert.pas that it would be helpful to have the files you have
so I can try to identify what changes we made broke this. It also indicates
that we don't have unit tests for this. I'll ask that we remedy this issue.
Cheers,
Bruneau.
Well I do not know what is wrong, bu in d2006 runtime and designtime works
fine
I can fetch params on design time and have no eror in runtime.
I will send you both OPToSOAPDomConv.pas (d2006 and d2007), I find that
error is in
function TSOAPDomConv.ReadVarArrayDim(...) - you will see.
I do not try to figureout why you use varIndex instead of "I" var from
for...next, but there is problem.
But some else is error is because if I change that function I still can not
fetch params in designtime.
"Jean-Marie Babet" <bba...@borland.com> wrote in message
news:471fb0e4$1...@newsgroups.borland.com...
Thank you for the additional info. Greatly appreciated.
> But some else is error is because if I change that function I still can
not
> fetch params in designtime.
NOTE: Even if you identify the issue and rebuild your app, the design-time
behaviour will remain the same is it's bound to the soaprtl package. Once we
identify the problem, we can rebuild the SOAP runtime package ( I can send
you a .dpk file to do that) and then the design-time behaviour will work!
Cheers,
Bruneau.
Original D2007
....
Result[VarIndex] := TypeTranslator.CastSoapToVariant(SoapTypeInfo,
ChildNode.Text);
end else
Result[VarIndex] := NULL;
Inc(VarIndex);
end;
end;
end;
But should be:
....
Result[VarIndex] := TypeTranslator.CastSoapToVariant(SoapTypeInfo,
ChildNode.Text);
end else
Result[VarIndex] := NULL;
end;
Inc(VarIndex); //now is on for...next - not under "if IsVarVarray or..."
condition
end;
end;
function from d2006 work fine, but will fail on some point when condition
for "Skip non-valid nodes" would be trigered.
I beleive that is the sollution, (I tested and work fine) so if you have
that soaprtl - send me please - it is realy bad when I must define
parameters twice (first time for DataSet and second time for ClientDataSet)
If you will send me a package, send me on my mail address - the one from I
send OPToSOAPDomConv.pas to you! Do not send on mail from this post.
Thanx
"Jean-Marie Babet" <bba...@borland.com> wrote in message
news:471fbb39$1...@newsgroups.borland.com...
You are right. It looks like this adjustment was introduces as a result for
my QC 22485. I provided a sample of how to adjust it (correct for that
codebase). I guess there was a mixup when the adjustment got into the
codebase, and they put the increment on the wrong blocklevel.
Let's cross or fingers for a fix in the next update :)
Kind regards, Atle.
Thank very much you for pinpointing the problem as I have not had the time
to do any investigation. I'll now go to see if I can get this fix approved
for a patch. Keeping my fingers crossed.
Cheers,
Bruneau.
PS: I'll update the unit tests to cater for this too.