Writing Web Connection Functions

 <  Day Day Up  >  

Web Connection server functions typically look in either the QueryString or the post buffer for parameters; then they construct a data command ( SELECT , INSERT , UPDATE , or DELETE ) and execute it; finally, if a SELECT was issued, the results are sent back.

There are five objects in the ASP model. Web Connection has classes that mimic each of them. One mimics the Request object, and another the Response object. I like to instantiate these two objects in my Web Connection code with the names Request and Response , so that I forget which language I'm in and start writing in Visual BasicScript.

Passing Parameters

There are two ways you can send data to a Web page. One is called GET and the other is called POST . GET means you can see the parameters, whereas POST means you can't.

GET Parameters

In an ASP program, the following statement

 

 lcName = request("Name") 

will return the value of Name in a URL that looks like this:

http://www.lespinter.com/subscriptions/login.asp?name=JoeBob

Web Connection has a Request object, which works a lot like Internet Explorer's Request object. However, Web Connection uses the slightly more formal syntax

 

 lcEverything = Request.QueryString() 

for the entire string, or

 

 lcName = request.QueryString("Name") 

for the Name value. However, because these are programs talking to programs, we generally simply separate the parameters with tildes ("~") and count them, like this:

 

 lcName = request.QueryString(3) 

That's slightly confusing because the first parameter is the class library name and the function name is the second one, making your first parameter the third one as far as Web Connection is concerned . You'll get used to it.

Here's an example: The following URL sends the name of a table, a key field, and a value from a user who has just picked a name from a drop-down list of customers in Alabama and wants the customer record:

http://www.lespinter.com/wconnect/wc.dll?MyDataServer~GetOneRecord~Customers~CustID~3012214

The server code to respond to this might be as shown in Listing 5.4.

Listing 5.4. Web Connection Function to Return a Single Record
 FUNCTION GetOnerecord pTable = Request.QueryString(3) pKeyField = Request.QueryString(4) pKeyValue = Request.QueryString(5) cmd = [SELECT * FROM ] + pTable + [ WHERE ] + pKeyField + [=] + pKeyValue cmd = cmd + [ INTO CURSOR C1] &Cmd CursorToXML ( "C1", "lcXML" ) USE IN C1 USE IN ( pTable ) Response.Write ( lcXML ) ENDFUNC 

However, there are limits to the size of the GET string, which I think is about 128 characters . It's irrelevant, though, because we generally don't want to send our data across the Internet in clear text that absolutely anyone can read, so we'll rarely use GET . Instead, we'll use POST , which stores the variables in a bag called the post buffer . They can also be encrypted, which is what you'll eventually want to do with sensitive information.

POST Variables

If you instead stuff values into the post buffer, they're hidden. To add a variable and its corresponding value to the post buffer, in your client program you might have this:

 

 oIP.AddPostKey ( Value, "key" ) 

The entire URL is then simply

http://www.lespinter.com/wconnect/wc.dll?MyDataServer~ShowMeDaData

Any parameters, records being sent to be stored, or whatever, are no one's business but your own. There's an AddPostKey function for just that purpose, as you'll see shortly.

GET and POST are only important when sending data or requests to a server. Servers send back whatever you want. It can be an HTML page, of course; but it can also be XML, or a DBF, or an encrypted string.

The next few lines are calls to the WWIPSTUFF class library that's included in Web Connection. It essentially sends a request to the server, waiting for a string containing the results to be returned in the variable lcBuffer .

I've chosen to demonstrate two ways to pass data back: a DBF and an XML string. If a DBF is returned, you just use StrToFile() to turn it back into a DBF and APPEND FROM to read it into the CARRIER cursor. If an XML string is created on the server and returned, it's converted back to a cursor when it's received. In either event it takes about a second (see Listing 5.5).

Listing 5.5. Using the Post Buffer to Send Parameters to the Web Server
 lnConnect = o.HTTPConnect ( Server )   IF lnConnect <> 0      MessageBox ( ;        [Couldn't connect to Internet Server], ;        64, _Screen.Caption )      .cmdCancel.Click   ENDIF   lcBuffer = []   lnBufLen = 0   o.AddPostKey  ( [RESET] )   o.AddPostKey  ( [ParmC], ParmC )   o.HTTPGetEx   (  FuncC,  @lcBuffer, @lnBufLen  )   SELECT Carrier   ZAP   DO CASE      CASE gcMethod = [DBF]    StrToFile     (  lcBuffer, [Carrier.DBF] )    APPEND FROM Carrier.DBF    DELETE FILE Carrier.DBF      OTHERWISE        && must be XML    lcXML = ALLTRIM( lcBuffer )    oXML.XMLToCursor ( lcXML,[Carrier] )   ENDCASE ENDIF ENDWITH WITH THISFORM.List1 IF _Tally > 0    SCAN     .AddListItem ( Company      )      Row = .NewItemID       .AddListItem ( City,    Row, 2)        .AddListItem ( Region,  Row, 3)        .AddListItem ( Cust_ID, Row, 4)    ENDSCAN    .ListIndex   =  1    .Selected[1] = .T.    THISFORM.cmdSelect.Enabled = .T.  ELSE    THISFORM.cmdSelect.Enabled = .F. ENDIF ENDWITH ENDPROC 

The AddPostKey method stuffs strings into the HTTP transport and sends them over. It's the cleanest way to send strings that contain blanks; otherwise you get all of those funny tildes and pluses.

Show All Customers is even easier; however, it's not advisable in most cases. I'm only doing it here because I know there are just a few records in the table (see Listing 5.6).

Listing 5.6. Code to Return All Customers
 PROCEDURE cmdall.Click SELECT Carrier ZAP THISFORM.List1.Clear FuncC = Prefix +( gcAllCustomers ) lnConnect = o.HTTPConnect ( Server ) IF lnConnect <> 0    MessageBox ( ;     [Couldn't connect to Internet Server], ;     64, _Screen.Caption )    cmdCancel.Click ENDIF lcBuffer = [] lnBufLen = 0 o.HTTPGetEx   (  FuncC,  @lcBuffer, @lnBufLen ) DO CASE    CASE gcMethod = [DBF]     StrToFile ( lcBuffer, [Carrier.DBF] )     SELECT Carrier     APPEND FROM Carrier.DBF     DELETE FILE Carrier.DBF    OTHERWISE        && must be XML     lcXML = ALLTRIM( lcBuffer )     oXML.XMLToCursor ( lcXML, [Carrier] ) ENDCASE WITH THISFORM.List1 SCAN     .AddListItem ( Company       )      Row = .NewItemID     .AddListItem ( City,    Row, 2)     .AddListItem ( Region,  Row, 3)     .AddListItem ( Cust_ID, Row, 4) ENDSCAN .ListIndex   =  1 .Selected[1] = .T. ENDWITH ENDPROC 

Think through the code for a few minutes and you'll see what's going on. You send off a query in the first parameter of HttpGetEx and then wait for the answer to be returned in lcBuffer as a string. You'll then convert it from either a DBF or from XML.

An XML Primer

XML is simplicity itself. (We'll talk about it in detail in Chapter 7, "XML.") If you have a CUSTOMER record with fields NAME , PHONE , and BALANCE , the XML of that record will look like this:

 

 <name>Joe Blow</name> <phone>555-1212</phone> <balance>123.45</balance> 

All data is converted to strings for XML transport. The XMLTOCURSOR() method of WWIPSTUFF class converts it back to the correct data types, using the corresponding field names in an open cursor to type the data.

The method call

 

 lcXML = oXML.CursorToXML() 

reads the currently open cursor and stores its XML representation in string lcXML . Its inverse function is

 

 oXML.XMLtoCursor ( lcXML ) 

which takes the string and dumps it into the cursor that's open in the current work area, using field names alone to determine what goes where and what data types to use. (It doesn't have to be the current work area, but I'm trying to make this as simple as possible.)

You can also use something called a DTD. There are thick books about XML, and you don't need to know any of it for what we're doing here. If you're one of those anal-retentive types who delights in theoretical purity, you're reading the wrong book.

The Customer Form

The Customer form is based on the StandardForm template. I included some basic capabilities in StandardForm , but a few additional features need to be added for each form that we build. The customer form appears in Figure 5.2.

Figure 5.2. The Customer form.

graphics/05fig02.jpg


The Load event creates a cursor that matches the data source (see Listing 5.7). If you're using SQL Server, the FoxPro data types are slightly different: SQL's Text is our Memo , Money is our Y field, and TinyInt and Smallint are just Int . For SQL VarChar , you can use either Memo or Char .

Listing 5.7. Load Event for the Form
 PROCEDURE Load CREATE CURSOR Customer (;  CUST_ID    Char( 6), ;  COMPANY    Char(40), ;  CONTACT    Char(30), ;  TITLE            Char(30), ;  ADDRESS    Char(60), ;  CITY        Char(15), ;  REGION           Char(15), ;  POSTALCODE    Char(10), ;  COUNTRY    Char(15), ;  PHONE            Char(24), ;  FAX        Char(24), ;  MAXORDAMT    Y      ) ENDPROC 

The users have to go to the server to pick a record. That's why, unlike what we're used to in the FoxPro world, the screen in most SQL apps is initially empty. The Find function described in Listing 5.8 lets them find a record to display on the form.

Listing 5.8. Click Event Code for the Find Button
 PROCEDURE cmdFind.Click WITH THISFORM DO FORM GetCust TO CustKey  && GetCust is a MODAL form IF NOT     EMPTY ( CustKey )    o.HTTPConnect ( Server )    lcBuffer = []    lnBufLen = 0    o.HTTPGetEx ( Prefix + gcSelectedCustomer + [~] ;         + CustKey, @lcBuffer, @lnBufLen )    IF NOT EMPTY ( lcBuffer )       SELECT CUSTOMER       ZAP       DO CASE         CASE gcMethod = [DBF]             StrToFile     (  lcBuffer, [Carrier.DBF] )             APPEND FROM Carrier.DBF             DELETE FILE Carrier.DBF         OTHERWISE        && must be XML             lcXML = ALLTRIM( lcBuffer )             oXML.XMLToCursor ( lcXML, [Customer])       ENDCASE    ENDIF    .Refresh    .cmdEdit.Enabled   = .T.    .cmdDelete.Enabled = .T.  ELSE    .cmdEdit.Enabled   = .F.    .cmdDelete.Enabled = .F. ENDIF .cmdNext.Enabled = .T. .cmdPrev.Enabled = .T. ENDWITH ENDPROC 

They might just want to add a record. See the template cmdAdd.click code shown in Listing 5.9 to see what happens here. Except for our code to ensure that the cursor is zapped before the default cmdADD.Click method code runs, there's little difference.

Listing 5.9. Click Event Code for the Add Button
 PROCEDURE cmdAdd.Click SELECT Customer ZAP DODEFAULT() ENDPROC 

There's no cmdEdit.Click code because it's exactly the same as the template code ”enable the input fields, then disable all buttons except Save and Cancel. Note that in the template code a form property called Adding is set to True during an add, because it's very, very important when it comes time to save changes or additions.

 <  Day Day Up  >  


Visual Fox Pro to Visual Basic.NET
Visual FoxPro to Visual Basic .NET
ISBN: 0672326493
EAN: 2147483647
Year: 2004
Pages: 130
Authors: Les Pinter

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net