Delphi 6 Update 2 # BUG and its solution Borland released the second patch for Delphi 6 meaning, has great enhancements in SOAP / Web Service development, see "Delphi 6.02 preemptive research - BizSnap / Soap / WebService Four - Patch 2 # meaning. " However, there is an aspect I have not said in that article, that is, use SOAP for multi-storey application development. At that time, I was just about the way, I didn't find anything more different from the patch, so I didn't care, until short ago, a netizen named LuoQian sent me Mail asking about this question about this question, I noticed that Delphi 6 Update 2 had a considerable change (of course not on the surface). And there is a small bug. First, the example in "Delphi 6 preemptive research - BizSnap / SOAP / WebService" three - Soap implementation three-layer database application "is a WebService three-layer data application. When the auto-inquiry shown in the appearance is selected, "NO" is selected when generating a server interface, and then new SOAP Server Data Module is created, and other operations are the same as "Three". Enter the IE after completion: http: // localhost: 1024 / demo3.wadsoapdemo3 / WSDL will be able to see the following interface list, compared to "three", you can see an added IappServersoAP interface, and its IWSDLPublish interface The Namespace URI is also different.
Port TypeNamespace URIDocumentationWSDLIAppServerurn: Midas-IAppServerIAppServerIAppServerSOAP http://www.borland.com/namespaces/Types IAppServerSOAP ISoapDemo3DMurn: SvrDMSoap-ISoapDemo3DMISoapDemo3DMIWSDLPublishhttp: //www.borland.com/namespaces/TypesLists all the PortTypes published by this ServiceIWSDLPublish If you pay attention, then you can also Find a problem, namely: Enter http: // localhost: 1024 / demo3.wadsoapdemo3 Will see a page like Delphi 6.02 written in a page, which is not normal. When writing a client program, the problem will appear: Drake pull in the clientDataSet's proviker, will not see any available ProviderName, but a flashing server form indicates that the server is running. You can see the following SOAP error response by viewing the record information of Web App Debugger: XML Version = "1.0" Encoding = 'UTF-8'?>
NO Invokable Class Registered That Implements InterfaceSoApmidas.iappServersoAP of (SOAP ACTION / PATH)
"http://www.borland.com/namespaces/types-iappserversoap"
faultstring>
soap-env: fault>
soap-env: body>
soap-env: envelope>
Note the information in the FaultString tag, which illustrates the cause of the error is "The registered Iappserversoap interface implementation that is not adjustable". If you ignore this problem, write DataSetProvider1 directly to the ProviderName property of the ClientDataSet1, and set the clientDataSet1's Active property to true, which is an exception, and its content is the content of the FAULTSTRING. I really like almost all products of Borland, including Delphi, and very trust Borland, this feeling derived from dozens of different Borland products and their different versions used in the seventh year, so I don't like some people. There is no reason to blame the development tool with bug when I encounter a problem. Although there are many rumors say how Borland's products bug, in fact, there is a bug, I don't say Borland, there is no bug, Borland, there is also a bug, I have mentioned several times in this site, do you mention that Microsoft has no bug? ? But this time, I can almost definitely brought by Delphi 6 Update 2, because I am doing step by step by patch 2 #, I will do it in the steps above, there is no problem, I played patch 2 # Such a problem. Even so, I still have to find specific evidence to prove that this is a bug and finds a solution, so I read some SOAP-related source code of Delphi 6.02, and debugged. Attachment: "Set Source Code View and Debug" SOAP Some Source Code View Settings: Select Tools | Environment Options in Delphi 6 Select the library page, join the path in Browsing Path: $ (Delphi) / Source / Soap, then you can in the program Quickly jump to the corresponding SOAP source file via Ctrl MouseleftButton. Source Commissioning Settings: Select Project | Options in Delph 6 Select the Compiler page. After selecting the Use Debug DCUS in the debugging box, recompilate the program, you can debug into the source code to enter the VCL. By tracking debugging discovery abnormality occurs in Procedure THTTPSOAPSCALINVOKER.DISPATCHSOAP in the SOAPHTTPSINV unit: ...
IF intfinfo = nil then
Raise Exception.createfmt (SinvinterFacenotReg, [soapaction])
Else if INVCLASSTYPE = NIL THEN
Raisenointfexception (soapaction)
...
Because INVCLASSTYPE is NIL, it causes the exception. This provides information and the previous error information is actually the same: that is, the implementation class of the IappserversoAP interface does not exist or not registered. So I found the definition of the Iappserversoap interface, in the SOAPMIDAS unit: iappserversoap = interface (Iinvokable) ['{C99F4735-D6D2-495C-8CA2-E53E5A439E61}']
Function SAS_Applyupdates (...): olevariant; stdcall;
Function Sas_getRecords (...): olevariant; stdcall;
Function Sas_DataRequest (...): Olevariant; stdcall;
Function Sas_getProvidernames: TwidEStringDynaRray; stdcall;
Function Sas_getparams (...): olevariant; stdcall;
Function SAS_ROWREQUEST (...): olevariant; stdcall;
Procedure sas_execute (...); stdcall;
END;
People who are familiar with MIDAS technologies have seen this code and immediately find that it is extremely similar to the Iappserver interface, just in Iappserver, those methods are starting with AS_, and here is starting with SAS_. So why you already have an Iappserver interface, Borland also add such an IappServersoAP interface to Update 2? Before playing patch 2, I also read some of the SOAP's code. At that time, SOAP Server Data Module was derived from Iappserver, although Iappserver is derived from Iinvokable (according to Delphi 6 requirements, all SOAP interfaces must be from Iinvokable from Iinvokable Interface derived), but in fact IINVOKABLE is derived directly from Iinterface, which is exactly the same as IINTERFACE, and IINTERFACE is actually the ancestral interface of all COM interfaces - INKNown, and Iappserver is from the IDispatch interface (a main interface for COM for Automation for Automation Of course, its ancestors are also iUnknown, which is derived, so it is not possible to use IAPServer directly. There is a comment in front of the IappserversoAP interface definition, and it is true that IAPPServersoap is called with the stdcall type method to replace the SAFECALL type in Iappserver, which is not supported in the environment where SaFECALL can also implement the IappServer function. This is the reason for IappserversoAP. It's much better to understand these. All SOAP Server Data Module is derived from TSOAPDataModule, which is defined in the SOAPDM unit, which is as follows: {ketpserversoap}
Function SAS_Applyupdates (...): Olevariant; Virtual; stdcall;
Function Sas_getRecords (...): Olevariant; Virtual; stdcall;
Function SAS_DATAREQUEST (...): Olevariant; Virtual; stdcall;
Function Sas_getProvidernames: TwidestringDynaRray; Virtual; StdCall;
Function Sas_getparams (...): olevariant; virtual; stdcall;
Function SAS_RowRequest (...): Olevariant; Virtual; stdcall;
Procedure sas_execute (...); virtual; stdcall;
Here is the implementation of the IappserversoAP interface. Since all SOAP Server Data Module is derived from TSoApDataModule, the implementation class of the Iappserversoap interface must be implemented, but is there registered? There is the following code in our Soap Server Data Module unit - Svrdmsoap: Procedure TSoApDemo3DmcreateInstance (Out Obj: TOBJECT);
Begin
Obj: = TSOAPDEMO3DM.CREATE (NIL);
END;
INITIALIZATION
Invregistry.registerInvokableClass (TSoAPDemo3DM, TSoAPDemo3dmcreateInstance);
Obviously it has been registered, but why will it be wrong? Take a look at the WSDL of the IsoapDemo3DM interface ... How is there only as_xxx? No SAS_XXX? It turns out that the server only exports the Iappserver interface and does not export the IappServerse interface. This is where the problem lies! Let's take a look at the Svrdmsoap unit: IsoapDemo3DM = Interface (Iappserver)
['{4F618288-9F81-4090-81EF-4ACE0BF6D0BE}']
END;
TSOAPDemo3DM = Class (TSoApDataModule, IsoapDemo3DM, Iappserver)
It turns out that ISOAPDEMO3DM is actually derived from the Iappserver interface, apparently this is a bug of SOAP Server Data Module Wizard, which is still in the Iappserver interface to generate SOAP Server Data Module. If you know the problem, you will do it. Both IappServer in the above code is changed to IappServersoAP, and then recompile. Let's take a look at the client program, everything is normal, IsoapDemo3DM WSDL also exports SAS_XXX, especially hhttp: // localhost: 1024 / demo3.wadsoApDemo3 can also see the standard Delphi 6.02 WebService page. At this point, this bug has been completely solved. In addition, it is necessary to add that this problem does not exist in C Builder 6. [Mental Studio] Raptor APR.23-02