.NET Framework
Re: cookies and wc files
>
<>I think part of my problem is not fully understanding objects. I can see that I have a server object and then I create a process object of which I think oCGI and oHTML properties of the process (I think they might be objects themselves, but I'm not sure). Then there is a session object that I was creating, but then you use THIS.initSession() which appears to be a process object method. I'm trying to figure out the relationships/dependentcies of the differect objects that are being used in the basic wc framework using cookies.<>
Prentiss,
I very strongly recommend <>'Object Orientation in Visual FoxPro'<> by Savannah Brentnall.
Here are some real basics about objects. <>First<>, there should be one for each distinct entity or 'actor'. <>Second<>, you have to create them in a way that they will exist for as long as they are needed, but no longer. And <>third<>, you need to be certain you can refer to any object from any other object that may need its services. Without this, you could not contact any of the objects that you create.
A 'framework' such as Rick's WC classes handle all of this for you, so all you need to do is learn how to use it. Without a framework, you also have to design your own way to make all of those things happen. A framework design reflects decisions that were made about how to instantiate, reference and release its objects.
So what are the important objects in a WC app?
The <>Server<> object runs all of the time and just waits for web requests. It knows how to initiate additional framework objects as needed, and how to call the components that you write. It is very different from a LAN-based VFP application, in that it serves multiple users at the same time.
The <>Request<> object is used to analyze all attributes about the incoming web hit (the user's request). It is instantiated and managed by the server object. It is always ready and waiting for you.
The HTML or <>Response<> object handles your output. It uses a helper object, the header object, to create the required HTTP header to go with it. Since the header is required, the framework will create a default one for you, unless you specifically do something to create your own. Unlike the Request object, the Response object is not created automatically by the Server object. (See below.)
The <>Process<> object is at the center of the WC developer's (ie, your) universe. It is created by the server object when appropriate web hits come in. It ties the Request to the Response. That is, you analyze what the user asked for in the Request and you create an appropriate (usually HTML) Response. It is so likely that you will want to use a wwHTML object in creating this response, that the process class just creates an empty one for you. Once the Process object is done processing, which occurs specifically at the end of your page's method code, the framework handles the mechanics of sending any output that you've sent to the Response object back along to the Server. It also releases the Response object.
The Process object also sets up the object references that you need to refer to the Request and Response objects. This used to be accomplished via its properties oHTML and oCGI. Thus you can refer to THIS.oHTML or THIS.oCGI. The sole point of these properties is to give you a handle to the other objects, so you can refer outwardly to their properties and methods while you are processing. For various reasons, including achieving ASP syntax compatability, the current preferred approach in WC is also to create PRIVATE variables called Request and Response that refer to precisely the same two objects. This variable creation is accomplished right in your Process objects's Process() method. (If you think too many things are called 'Process', you're right .)
Finally, since the Process object only lives while one page is created, and the Server object is handling multiple users. There is nothing that handles one specific user throughout their time spent in your application. This is where the Session object comes in. It used to be that you had to instantiate this object yourself and set up and maintain your own object reference to it (loSession variable).
This was enough of a nuisance and people made enough mistakes with it that Rick beefed up the framework to add methods and properties to automate the process. The most important to the developer is the Process object's InitSession() method. This does many things for you. It both instantiates a Session object and it stores an object reference to it in the oSession property of the Process object. Thus you never need a loSession variable--instead refer to THIS.oSession. Further InitSession sets properties back in the Response object that automatically guarantee that a Cookie will be produced if this user did not already have one. This is a masterful illustration of 5 framework objects acting in concert (Process, Session, Request, Response, and Header) all in response to a single command from you. Not bad, eh?
<>Also, the header object. For some reason I felt that even after using THIS.initSession() that I still needed to create a loHeader object eventhough the documentation that I have read indicates that I do not need to so.<>
You should now feel confident to follow this thread yourself by reviewing the source code in the framework PRG files. Well, if not confident, just do it anyway :
wwProcess.InitSession() checks the wwCgi (Request) object to see if a cookie already exists. It then creates a wwSession object. It asks the session object if the session is already valid (i.e., if it's not the first hit for this user). Only on the first hit, it asks the Session object to create a new session record via the NewSession() method. It then talks to the Response object and sets its cAutoSessionCookie and cAutoSessionCookieName properties.
Now, when you move along to the output stage, yoy initiate the creation of your Response document by using either wwHTML::HTMLHeader() when you create a page in code or wwHTML::ShowHTMLFile(). Either of these calls wwHTML::ContentTypeHeader(). This function calls the wwHTTPHeader class, which among other things, checks back with the Response object to see if the cAutoSessionCookie property was set. If so, it calls its own AddCookie method to insert the cookie.
Whew! So you see, all you have to do is say THIS.InitSession() to get all of this done.
The other function of InitSession is to set an object reference to the session object, so you can talk to it. It stores that in oSession. This lets you simply call THIS.oSession.GetSessionVar and .SesSessionVar wherever you want.
If you have any doubts about what you've done in your page with cookies, add this method to your process class:<>< >
<
>
>FUNCTION ShowCookie LOCAL lcStr lcStr = '' DO CASE CASE NOT EMPTY( Response.AutoSessionCookie) lcStr = 'Setting cookie: ' + Response.AutoSessionCookieName + ; ' = ' + Response.AutoSessionCookie CASE VARTYPE( THIS.oSession) = 'O' AND ; VARTYPE( THIS.oSession.cSessionId) = 'C' AND ; NOT EMPTY( THIS.oSession.cSessionId) lcStr = 'Cookie in use: ' + THIS.oSession.cSessionId OTHERWISE lcStr = 'No Cookie!' ENDCASE RETURN m.lcStr ENDFUNC<> Now on any page method, just insert the line <>Response.SendLn( THIS.ShowCookie())<>. QUIZ: The session object stores all the session information to a DBF. There are two reasons other than performance, why it has to do it this way, instead of, say, storing them in a Server object array. Can you figure out why? Regards, -- Randy <
><