C ++ Builder 6 bizsnap/soap/WebService (2)-pass custom data through soap (change)

Source: Internet
Author: User

Note: Some changes have been made in this article, and some problems have been corrected. Because the original text cannot be modified, You Have To resend it.
Not long ago, I received emails from several friends about a problem they encountered when developing a WebService application as described in this article: An AV error occurred while compiling the sample program in this article using ISAPI. This article has been modified based on the improved program in this example. Note the bold content in this article.
-- 2002-8-17

In this article, we will provide a slightly complex example to implement the transmission of custom data types through soap. The function of this example is to obtain the data table content from the server through the ADO data access control, and then pass it to the client through soap for display.

Server:
1. New | WebServices | SOAP server application. For example, the icons in the upper left corner are identical to those in Delphi 6 + Update 2:

Select the web app debugger executeable type. The coclass name is wadsoapdemo2, for example:

After confirming, the system will automatically prompt whether to create an interface. For example, if you are sure to open the new interface wizard, if you want to add an interface later, you can select the SOAP server interface in new | WebServices to open the new interface Wizard:

2. In the new interface wizard, enter the interface name datatable to generate a SOAP server interface:

For other instructions on this wizard, see "C ++ Builder 6 bizsnap/soap/WebService (1) -- A Hello world! (1).
3.(Note: This part of the original text is incorrect. It is modified now)Create a new datamodule and add the following four database controls: adoconnection1, adodataset1, datasetprovider1, and clientdataset1. The attribute settings are as follows:

Adoconnection1 Connectionstring = "provider = sqloledb.1; persist Security info = false; user id = sa; initial catalog = northwind; Data Source = raptor/neutrino ";
Loginprompt = false;
Adodataset1 Connection = adoconnection1;
Commandtext = "select firstname, lastname from employees ";
Datasetprovider1 Dataset = adodataset1;
Clientdataset1 Providername = datasetprovider1;

The completed datamodule is as follows:

(Additional instructions on this part): "Unable load dbexpint. dll" error occurs when dbexpress is used for ISAPI, so use ADO instead. In addition, because there is no adoclientdataset control, otherwise, if it is Bde/dbexpress/ibexpress, only two controls are required. To put the data control in a separate datamodule, instead of a webmodule, see Web Application Execution Process-differences between wad, CGI, and ISAPI. This example is for reference only, we recommend that you use the SOAP server data module (for example, C ++ Builder 6 bizsnap (3) -- datasnap Database Application) in applications involving database operations.
4. saveall, unit1 is named mainwm, unit2 is named demo2dm, project1 is named demo2, and able is not renamed;
5. Add a custom class named tdatasetpack in the header file (datatable. h) of the interface unit, as shown below:

class TDataSetPack : public TRemotable {private :    int        FCount;    AnsiString FXMLData;public :    __fastcall TDataSetPack( TCustomClientDataSet * aClientDataSet )        : TRemotable(),        FCount( aClientDataSet->RecordCount ),        FXMLData( aClientDataSet->XMLData )    {    }__published:    __property int        Count   = { read = FCount   };     __property AnsiString XMLData = { read = FXMLData };};

The custom soap data type must be derived from the tremotable class, which is the same as that of Delphi. The xmldata attribute of clientdataset is added from Delphi 6. In fact, xmldata already contains the number of records. The Count attribute is not required. This attribute is added to demonstrate the use of custom soap data types. Note: Add # include <dbclient. HPP> to this header file.
5. define and implement the getemployeetable function. The method is the same as that in (1). below is the interface header file (datatable. h) and the unit file (datatable. the interface/class definition in CPP, the method we add, and its implementation:

// Datatable. H _ interface interface_uuid ("{CF057C28-4130-4508-9F24-0BBD1C2CA5F0}") idatatable: Public iinvokable {public: Virtual tdatasetpack * getemployeetable (void) = 0; // Add method}; typedef delphiinterface
 
  
_ Di_idatatable; // datatable. cppclass tdatatableimpl: Public tinvokableclass, public idatatable {public: tdatasetpack * getemployeetable (void); // Add method/* iunknown */hresult stdmethodcalltype QueryInterface (const guid & IID, void ** OBJ) {return getinterface (IID, OBJ )? S_ OK: e_nointerface;} ulong stdmethodcalltype addref () {return tinterfacedobject: _ addref ();} ulong stdmethodcalltype release () {return tinterfacedobject: _ release ();} /* ensures that the class is not abstract */void checkvalid () {delete new tdatatableimpl () ;}; // Implementation of the new method: // if it is a CGI/ISAPI application, you need to create datamodule1. For the corresponding changes, see the description later. // open clientdataset and construct tdatasetpack, // disable clientdataset and database connection // return result tdatasetpack * tdatatableimpl: getemployeetable (void) {// for CGI/ISAPI, this sentence is required. // application-> createform (_ classid (tdatamodule1), & datamodule1); datamodule1-> clientdataset1-> open (); tdatasetpack * P = new tdatasetpack (datamodule1-> clientdataset1); datamodule1-> clientdataset1-> close (); datamodule1-> adoconnection1-> close (); Return P ;}
 

Except for the implementation of methods, the other parts are basically the same as those in (1. The implementation function of this method, as described in the program, is used to retrieve a dataset and convert it to the data type we define and return it.
(Additional instructions on this part): Note that for CGI/ISAPI applications, datamodule1 is a dynamic creation (the reason is as described in "Web Application Execution Process-differences between wad, CGI, and ISAPI ), therefore, the corresponding project | source (demo2cgi. CPP/demo2isapi. in CPP), The automatically created statement is removed as follows.

Application-> createform (_ classid (twebmodule1), & webmodule1 ); // do not use this sentence for CGI/ISAPI applications. // application-> createform (_ classid (tdatamodule1), & datamodule1); Application-> Run ();

6. The registration interface and its implementation class are the same as those in (1), so we will not repeat them here.
7. compile and generate: demo2.exe;

Run demo2.exe first, and then start the web app debugger after registration. Open your browser and enter http: // localhost: 1024/demo2.wadsoapdemo2 to view a standard soap application description page. Click the corresponding link to view the relevant WSDL, here we can see the description of the custom data type, as shown in the following WSDL segment:

  <types>    <xs:schema targetNamespace="urn:DataTable" xmlns="urn:DataTable">      <xs:complexType name="TDataSetPack">        <xs:sequence>          <xs:element name="Count" type="xs:int"/>          <xs:element name="XMLData" type="xs:string"/>        </xs:sequence>      </xs:complexType>    </xs:schema>  </types>

Client Program:
1. New | application creates a general VCL application;
2. saveall, unit1 is named clnmain, and project1 is named client;
3. New | Web Services Importer:
Enter http: // localhost: 1024/demo2.wadsoapdemo2/WSDL/idatatable in the URL,

If you can see the correct XML document in the browser, select "Next" to generate the import result, for example:

The data type tdatasetpack, The idatatable interface, and its method getemployeetable defined on the server are available. After the selection, the interface unit is generated;
4. saveall: The idatatable unit is not renamed and saved, and then # include idatatable. h In clnmain;
5. Put a clientdataset, datasource, DBGrid, button, label, and other controls on the form. The following table lists the attributes of these controls:

Clientdataset1 All default
Performance1 Dataset = clientdataset1;
Dbgrid1 Datasource = performance1;
Button1 Caption = "fetch data ";
Label1 Caption = "count: 0 ";

The completed form is as follows:

6. Double-click button1 and enter the following program:

void __fastcall TForm2::Button1Click(TObject *Sender){    TDataSetPack * p = GetIDataTable()->GetEmployeeTable();    Label1->Caption = AnsiString( "Count:" ) + IntToStr( p->Count );        ClientDataSet1->XMLData = p->XMLData;}

7. Compile and run the program. Press button1 and dbgrid1 to display the content of the dataset returned by the server, and label1 to display the number of records, as shown in (this figure is still the data when Interbase is used );

This is just a simple example of database access. You can only retrieve the dataset from the server. In C ++ Builder 6, we have already combined the data set of the Midas/datasnap and the soap/WebService, you can use soap/WebService to implement very powerful database operation capabilities, which will be described in future articles.

[Mental Studio] apr.30-02

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.