Web Connection
Scope of variables
Gravatar is a globally recognized avatar based on your email address. Scope of variables
  n/a
  All
  Apr 20, 2012 @ 09:31am
I am still/again confused about this stateless nature of the Web application and in particular scope issues. When the user comes to my site, I force him to login with an e-mail address and password, look them up in a FoxPro table and determine what kind of access they should be allowed. How do I create memory variables or an object that will remain in scope in the various code behind programs throughout the users session? If I create a variable in the top-level Web connection executable, I presume it will remain in scope throughout, but will each individual visiting the website have their own set of these top-level variables?

Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  Ian G. Lloyd
  Potter Orr
  Apr 20, 2012 @ 11:06am
Potter... the place to keep user 'global' variables and their data is in the Session... look up the wwSession class in the Help file under Framework Support Classes... review the 'How It Works' topic... there is an explanation of how to utuilize this class... basically, the first time a user logs in and throughout the hit you can place 'global' variable/values in their session... then when they return you re-initialize these variable/values to 'maintain' their state for the logged in user... another way to maintain some state is to utilize a 'License Plate' methodology in the URL, though this is more involved... HTH...

I am still/again confused about this stateless nature of the Web application and in particular scope issues. When the user comes to my site, I force him to login with an e-mail address and password, look them up in a FoxPro table and determine what kind of access they should be allowed. How do I create memory variables or an object that will remain in scope in the various code behind programs throughout the users session? If I create a variable in the top-level Web connection executable, I presume it will remain in scope throughout, but will each individual visiting the website have their own set of these top-level variables?

Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  Rick Strahl
  Potter Orr
  Apr 20, 2012 @ 02:24pm
Potter,

You can't use 'global' variables in FoxPRo code to track users. Since many users access the same server and the same program they'd all share that same global variable and the results you'd get would not pertain to a specific user. That's a big no-no.

Globals CAN work if you have objects that can be shared. Good examples for this are things like a wwSql instance that can be shared (to avoid re-connecting to a SQL Server, a configuration class, global constants etc. etc.)

For any user storage that needs to persist across hits you can use either HTTP Cookies which is a low level operation you can manage yourself with Response.AddCookie() or Request.GetCookie() which stores single cookie values, or by using the wwSession class (Session to Server.oSession) which uses cookies but provides an easier storage mechanism for many values.

Ideally Session and/or Cookies should only be used to store very simple things like IDs that identify users, which you can use to load up more information from the database/your application. Don't store large pieces of data in there.

As Ian pointed out - take a look at the wwSession class in the documentation which should get you started and you cna then post here for more info.

+++ Rick ---



I am still/again confused about this stateless nature of the Web application and in particular scope issues. When the user comes to my site, I force him to login with an e-mail address and password, look them up in a FoxPro table and determine what kind of access they should be allowed. How do I create memory variables or an object that will remain in scope in the various code behind programs throughout the users session? If I create a variable in the top-level Web connection executable, I presume it will remain in scope throughout, but will each individual visiting the website have their own set of these top-level variables?



Rick Strahl
West Wind Technologies

Making waves on the Web

from Maui, Hawaii
Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  n/a
  Ian G. Lloyd
  Apr 21, 2012 @ 07:17pm
Ian,

Thanks. I read the help file sections (several times) and it looks like I can create a session, store data using sessionsetvar and retrieve it later with sessiongetvar.

What I could not figure out was where and how I get the wwsession started. Does it have to go in the WestWind program in c:\wconnect\... or in my code behind segments in c:\inetpub\wwwroot\...?

Potter


Potter... the place to keep user 'global' variables and their data is in the Session... look up the wwSession class in the Help file under Framework Support Classes... review the 'How It Works' topic... there is an explanation of how to utuilize this class... basically, the first time a user logs in and throughout the hit you can place 'global' variable/values in their session... then when they return you re-initialize these variable/values to 'maintain' their state for the logged in user... another way to maintain some state is to utilize a 'License Plate' methodology in the URL, though this is more involved... HTH...

I am still/again confused about this stateless nature of the Web application and in particular scope issues. When the user comes to my site, I force him to login with an e-mail address and password, look them up in a FoxPro table and determine what kind of access they should be allowed. How do I create memory variables or an object that will remain in scope in the various code behind programs throughout the users session? If I create a variable in the top-level Web connection executable, I presume it will remain in scope throughout, but will each individual visiting the website have their own set of these top-level variables?


Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  Rick Strahl
  Potter Orr
  Apr 22, 2012 @ 01:18am

You don't have to do anything other than making sure you add:

FUNCTION OnProcessInit()
this.InitSession()
* .... any other code that needs to happen at start of every request

into your OnProcessInit() function. This gets the session object initialized for all requests and makes the Session object available.

I'm surprised that you've come this far and have not yet had a need to use the Session object...

+++ Rick ---



Ian,

Thanks. I read the help file sections (several times) and it looks like I can create a session, store data using sessionsetvar and retrieve it later with sessiongetvar.

What I could not figure out was where and how I get the wwsession started. Does it have to go in the WestWind program in c:\wconnect\... or in my code behind segments in c:\inetpub\wwwroot\...?

Potter


Potter... the place to keep user 'global' variables and their data is in the Session... look up the wwSession class in the Help file under Framework Support Classes... review the 'How It Works' topic... there is an explanation of how to utuilize this class... basically, the first time a user logs in and throughout the hit you can place 'global' variable/values in their session... then when they return you re-initialize these variable/values to 'maintain' their state for the logged in user... another way to maintain some state is to utilize a 'License Plate' methodology in the URL, though this is more involved... HTH...

I am still/again confused about this stateless nature of the Web application and in particular scope issues. When the user comes to my site, I force him to login with an e-mail address and password, look them up in a FoxPro table and determine what kind of access they should be allowed. How do I create memory variables or an object that will remain in scope in the various code behind programs throughout the users session? If I create a variable in the top-level Web connection executable, I presume it will remain in scope throughout, but will each individual visiting the website have their own set of these top-level variables?





Rick Strahl
West Wind Technologies

Making waves on the Web

from Maui, Hawaii
Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  n/a
  Rick Strahl
  Apr 22, 2012 @ 08:12am
Thanks - as always. I understand but still don't know which piece of code should get the function OnProcessInit(). I do not have that function anywhere that I can find.

The way my application is structured, the entry point is a page called userin.alb (.alb is the extension I am using). The user provides a valid email address and password and clicks on a login button to start the process. Only if their information is valid will they be allowed to proceed so I guess this is their entry point. Should the function be in this code and be called by the login button click method?

Potter

You don't have to do anything other than making sure you add:

FUNCTION OnProcessInit()
this.InitSession()
* .... any other code that needs to happen at start of every request

into your OnProcessInit() function. This gets the session object initialized for all requests and makes the Session object available.

I'm surprised that you've come this far and have not yet had a need to use the Session object...

+++ Rick ---



Ian,

Thanks. I read the help file sections (several times) and it looks like I can create a session, store data using sessionsetvar and retrieve it later with sessiongetvar.

What I could not figure out was where and how I get the wwsession started. Does it have to go in the WestWind program in c:\wconnect\... or in my code behind segments in c:\inetpub\wwwroot\...?

Potter


Potter... the place to keep user 'global' variables and their data is in the Session... look up the wwSession class in the Help file under Framework Support Classes... review the 'How It Works' topic... there is an explanation of how to utuilize this class... basically, the first time a user logs in and throughout the hit you can place 'global' variable/values in their session... then when they return you re-initialize these variable/values to 'maintain' their state for the logged in user... another way to maintain some state is to utilize a 'License Plate' methodology in the URL, though this is more involved... HTH...

I am still/again confused about this stateless nature of the Web application and in particular scope issues. When the user comes to my site, I force him to login with an e-mail address and password, look them up in a FoxPro table and determine what kind of access they should be allowed. How do I create memory variables or an object that will remain in scope in the various code behind programs throughout the users session? If I create a variable in the top-level Web connection executable, I presume it will remain in scope throughout, but will each individual visiting the website have their own set of these top-level variables?





Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  Bob Roenigk
  Potter Orr
  Apr 22, 2012 @ 12:13pm
Hi Potter,

OnProcessInit() should be in your process class. Did you use the wizard from the WW Console app when you created your project? If so, you should have a stub of a process class already in your project. If not, you can use a wizard to create it for you. Here is the link to the documentation.

http://www.west-wind.com/webconnection/docs/_s9u01ofwb.htm

OnProcessInit() does not need to be in your code behind each page since it is called from wwprocess.

~bob



Thanks - as always. I understand but still don't know which piece of code should get the function OnProcessInit(). I do not have that function anywhere that I can find.

The way my application is structured, the entry point is a page called userin.alb (.alb is the extension I am using). The user provides a valid email address and password and clicks on a login button to start the process. Only if their information is valid will they be allowed to proceed so I guess this is their entry point. Should the function be in this code and be called by the login button click method?

Potter

You don't have to do anything other than making sure you add:

FUNCTION OnProcessInit()
this.InitSession()
* .... any other code that needs to happen at start of every request

into your OnProcessInit() function. This gets the session object initialized for all requests and makes the Session object available.

I'm surprised that you've come this far and have not yet had a need to use the Session object...

+++ Rick ---



Ian,

Thanks. I read the help file sections (several times) and it looks like I can create a session, store data using sessionsetvar and retrieve it later with sessiongetvar.

What I could not figure out was where and how I get the wwsession started. Does it have to go in the WestWind program in c:\wconnect\... or in my code behind segments in c:\inetpub\wwwroot\...?

Potter


Potter... the place to keep user 'global' variables and their data is in the Session... look up the wwSession class in the Help file under Framework Support Classes... review the 'How It Works' topic... there is an explanation of how to utuilize this class... basically, the first time a user logs in and throughout the hit you can place 'global' variable/values in their session... then when they return you re-initialize these variable/values to 'maintain' their state for the logged in user... another way to maintain some state is to utilize a 'License Plate' methodology in the URL, though this is more involved... HTH...

I am still/again confused about this stateless nature of the Web application and in particular scope issues. When the user comes to my site, I force him to login with an e-mail address and password, look them up in a FoxPro table and determine what kind of access they should be allowed. How do I create memory variables or an object that will remain in scope in the various code behind programs throughout the users session? If I create a variable in the top-level Web connection executable, I presume it will remain in scope throughout, but will each individual visiting the website have their own set of these top-level variables?






Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  Rick Strahl
  Potter Orr
  Apr 22, 2012 @ 03:09pm
You can also enable session state for individual Page classes by setting

EnableSessionState = .T.

in the declaration of properties for the page. This too fires InitSession() if it hasn't been fired yet.

Along the same lines:

Process.lEnableSessionState = .T.

can also be used (in pages or any other code) to do effectively the same thing.

+++ Rick ---


Thanks - as always. I understand but still don't know which piece of code should get the function OnProcessInit(). I do not have that function anywhere that I can find.

The way my application is structured, the entry point is a page called userin.alb (.alb is the extension I am using). The user provides a valid email address and password and clicks on a login button to start the process. Only if their information is valid will they be allowed to proceed so I guess this is their entry point. Should the function be in this code and be called by the login button click method?

Potter

You don't have to do anything other than making sure you add:

FUNCTION OnProcessInit()
this.InitSession()
* .... any other code that needs to happen at start of every request

into your OnProcessInit() function. This gets the session object initialized for all requests and makes the Session object available.

I'm surprised that you've come this far and have not yet had a need to use the Session object...

+++ Rick ---



Ian,

Thanks. I read the help file sections (several times) and it looks like I can create a session, store data using sessionsetvar and retrieve it later with sessiongetvar.

What I could not figure out was where and how I get the wwsession started. Does it have to go in the WestWind program in c:\wconnect\... or in my code behind segments in c:\inetpub\wwwroot\...?

Potter


Potter... the place to keep user 'global' variables and their data is in the Session... look up the wwSession class in the Help file under Framework Support Classes... review the 'How It Works' topic... there is an explanation of how to utuilize this class... basically, the first time a user logs in and throughout the hit you can place 'global' variable/values in their session... then when they return you re-initialize these variable/values to 'maintain' their state for the logged in user... another way to maintain some state is to utilize a 'License Plate' methodology in the URL, though this is more involved... HTH...

I am still/again confused about this stateless nature of the Web application and in particular scope issues. When the user comes to my site, I force him to login with an e-mail address and password, look them up in a FoxPro table and determine what kind of access they should be allowed. How do I create memory variables or an object that will remain in scope in the various code behind programs throughout the users session? If I create a variable in the top-level Web connection executable, I presume it will remain in scope throughout, but will each individual visiting the website have their own set of these top-level variables?








Rick Strahl
West Wind Technologies

Making waves on the Web

from Maui, Hawaii
Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  n/a
  Rick Strahl
  Apr 23, 2012 @ 06:33am
Rick,

The more I read your answers the less I think I know. What and where are "declaration of properties for the page" ?

Do the sample WestWind projects (TimeTrakker etc.) use Session? Maybe if I could see the use in action it would make more sense to me.

Potter


You can also enable session state for individual Page classes by setting

EnableSessionState = .T.

in the declaration of properties for the page. This too fires InitSession() if it hasn't been fired yet.

Along the same lines:

Process.lEnableSessionState = .T.

can also be used (in pages or any other code) to do effectively the same thing.

+++ Rick ---


Thanks - as always. I understand but still don't know which piece of code should get the function OnProcessInit(). I do not have that function anywhere that I can find.

The way my application is structured, the entry point is a page called userin.alb (.alb is the extension I am using). The user provides a valid email address and password and clicks on a login button to start the process. Only if their information is valid will they be allowed to proceed so I guess this is their entry point. Should the function be in this code and be called by the login button click method?

Potter

You don't have to do anything other than making sure you add:

FUNCTION OnProcessInit()
this.InitSession()
* .... any other code that needs to happen at start of every request

into your OnProcessInit() function. This gets the session object initialized for all requests and makes the Session object available.

I'm surprised that you've come this far and have not yet had a need to use the Session object...

+++ Rick ---



Ian,

Thanks. I read the help file sections (several times) and it looks like I can create a session, store data using sessionsetvar and retrieve it later with sessiongetvar.

What I could not figure out was where and how I get the wwsession started. Does it have to go in the WestWind program in c:\wconnect\... or in my code behind segments in c:\inetpub\wwwroot\...?

Potter


Potter... the place to keep user 'global' variables and their data is in the Session... look up the wwSession class in the Help file under Framework Support Classes... review the 'How It Works' topic... there is an explanation of how to utuilize this class... basically, the first time a user logs in and throughout the hit you can place 'global' variable/values in their session... then when they return you re-initialize these variable/values to 'maintain' their state for the logged in user... another way to maintain some state is to utilize a 'License Plate' methodology in the URL, though this is more involved... HTH...

I am still/again confused about this stateless nature of the Web application and in particular scope issues. When the user comes to my site, I force him to login with an e-mail address and password, look them up in a FoxPro table and determine what kind of access they should be allowed. How do I create memory variables or an object that will remain in scope in the various code behind programs throughout the users session? If I create a variable in the top-level Web connection executable, I presume it will remain in scope throughout, but will each individual visiting the website have their own set of these top-level variables?








Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  Rick Strahl
  Potter Orr
  Apr 23, 2012 @ 09:16pm
Potter,

Take a look at the docs. They do explain where stuff goes.

Yes all the samples we build in the training use Session and use InitSession() to set up global sessions.

It's really not very difficult. Use the help file and follow the references when in doubt.

+++ Rick ---


Rick,

The more I read your answers the less I think I know. What and where are "declaration of properties for the page" ?

Do the sample WestWind projects (TimeTrakker etc.) use Session? Maybe if I could see the use in action it would make more sense to me.

Potter


You can also enable session state for individual Page classes by setting

EnableSessionState = .T.

in the declaration of properties for the page. This too fires InitSession() if it hasn't been fired yet.

Along the same lines:

Process.lEnableSessionState = .T.

can also be used (in pages or any other code) to do effectively the same thing.

+++ Rick ---


Thanks - as always. I understand but still don't know which piece of code should get the function OnProcessInit(). I do not have that function anywhere that I can find.

The way my application is structured, the entry point is a page called userin.alb (.alb is the extension I am using). The user provides a valid email address and password and clicks on a login button to start the process. Only if their information is valid will they be allowed to proceed so I guess this is their entry point. Should the function be in this code and be called by the login button click method?

Potter

You don't have to do anything other than making sure you add:

FUNCTION OnProcessInit()
this.InitSession()
* .... any other code that needs to happen at start of every request

into your OnProcessInit() function. This gets the session object initialized for all requests and makes the Session object available.

I'm surprised that you've come this far and have not yet had a need to use the Session object...

+++ Rick ---



Ian,

Thanks. I read the help file sections (several times) and it looks like I can create a session, store data using sessionsetvar and retrieve it later with sessiongetvar.

What I could not figure out was where and how I get the wwsession started. Does it have to go in the WestWind program in c:\wconnect\... or in my code behind segments in c:\inetpub\wwwroot\...?

Potter


Potter... the place to keep user 'global' variables and their data is in the Session... look up the wwSession class in the Help file under Framework Support Classes... review the 'How It Works' topic... there is an explanation of how to utuilize this class... basically, the first time a user logs in and throughout the hit you can place 'global' variable/values in their session... then when they return you re-initialize these variable/values to 'maintain' their state for the logged in user... another way to maintain some state is to utilize a 'License Plate' methodology in the URL, though this is more involved... HTH...

I am still/again confused about this stateless nature of the Web application and in particular scope issues. When the user comes to my site, I force him to login with an e-mail address and password, look them up in a FoxPro table and determine what kind of access they should be allowed. How do I create memory variables or an object that will remain in scope in the various code behind programs throughout the users session? If I create a variable in the top-level Web connection executable, I presume it will remain in scope throughout, but will each individual visiting the website have their own set of these top-level variables?











Rick Strahl
West Wind Technologies

Making waves on the Web

from Maui, Hawaii
Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  n/a
  Rick Strahl
  Apr 24, 2012 @ 11:09am
Rick,

I find it very difficult. I have read and Read the documentation and all of the methods you have suggested in previous responses with no luck. The first interaction a user has is when they fill in an email address and a password and click the login button. Shown below is the code that fires on from that button click. At the line "Session.SetSession.... I get the error "Session is not an object" (arrow added)

FUNCTION userloginbutton_click()
SET EXCLUSIVE off
IF NOT USED('person')
USE f:\albat9\person ORDER email IN 0
SELECT person
ELSE
SELECT person
SET ORDER TO email
ENDIF

*THIS.InitSession("albweb")
EnableSessionState = .T.

SEEK UPPER(ALLTRIM(this.username.text))
IF EOF()
* WAIT WINDOW 'Did not find: '+UPPER(ALLTRIM(this.username.text))
this.ErrorDisplay.ShowError("The combination of user name and password could not be found")
* this.loginstatus.text = "Not Logged In"
ELSE
*-------- OK: login successful create a session object
* losession = CREATEOBJECT("wwsession")

IF ALLTRIM(this.userpwd.text) == ALLTRIM(person.pwd)
* this.ErrorDisplay.ShowError(this.username.text+ " FOUND & passord OK")
*------- Set values in global variables
mcurrnum = person.num
---------> Session.SetSessionVar("personnum",person.num)


Potter,

Take a look at the docs. They do explain where stuff goes.

Yes all the samples we build in the training use Session and use InitSession() to set up global sessions.

It's really not very difficult. Use the help file and follow the references when in doubt.

+++ Rick ---


Rick,

The more I read your answers the less I think I know. What and where are "declaration of properties for the page" ?

Do the sample WestWind projects (TimeTrakker etc.) use Session? Maybe if I could see the use in action it would make more sense to me.

Potter


You can also enable session state for individual Page classes by setting

EnableSessionState = .T.

in the declaration of properties for the page. This too fires InitSession() if it hasn't been fired yet.

Along the same lines:

Process.lEnableSessionState = .T.

can also be used (in pages or any other code) to do effectively the same thing.

+++ Rick ---


Thanks - as always. I understand but still don't know which piece of code should get the function OnProcessInit(). I do not have that function anywhere that I can find.

The way my application is structured, the entry point is a page called userin.alb (.alb is the extension I am using). The user provides a valid email address and password and clicks on a login button to start the process. Only if their information is valid will they be allowed to proceed so I guess this is their entry point. Should the function be in this code and be called by the login button click method?

Potter

You don't have to do anything other than making sure you add:

FUNCTION OnProcessInit()
this.InitSession()
* .... any other code that needs to happen at start of every request

into your OnProcessInit() function. This gets the session object initialized for all requests and makes the Session object available.

I'm surprised that you've come this far and have not yet had a need to use the Session object...

+++ Rick ---



Ian,

Thanks. I read the help file sections (several times) and it looks like I can create a session, store data using sessionsetvar and retrieve it later with sessiongetvar.

What I could not figure out was where and how I get the wwsession started. Does it have to go in the WestWind program in c:\wconnect\... or in my code behind segments in c:\inetpub\wwwroot\...?

Potter


Potter... the place to keep user 'global' variables and their data is in the Session... look up the wwSession class in the Help file under Framework Support Classes... review the 'How It Works' topic... there is an explanation of how to utuilize this class... basically, the first time a user logs in and throughout the hit you can place 'global' variable/values in their session... then when they return you re-initialize these variable/values to 'maintain' their state for the logged in user... another way to maintain some state is to utilize a 'License Plate' methodology in the URL, though this is more involved... HTH...

I am still/again confused about this stateless nature of the Web application and in particular scope issues. When the user comes to my site, I force him to login with an e-mail address and password, look them up in a FoxPro table and determine what kind of access they should be allowed. How do I create memory variables or an object that will remain in scope in the various code behind programs throughout the users session? If I create a variable in the top-level Web connection executable, I presume it will remain in scope throughout, but will each individual visiting the website have their own set of these top-level variables?











Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  n/a
  Potter Orr
  Apr 24, 2012 @ 01:02pm
Potter
I thinks it's This.oSession.SetSessionVar("personnum",person.num).......instead of your Session.SetSessionVar("personnum",person.num)...
Hope this helps...
Cheers...
Arnold
---------------------------------------------------


Rick,

I find it very difficult. I have read and Read the documentation and all of the methods you have suggested in previous responses with no luck. The first interaction a user has is when they fill in an email address and a password and click the login button. Shown below is the code that fires on from that button click. At the line "Session.SetSession.... I get the error "Session is not an object" (arrow added)

FUNCTION userloginbutton_click()
SET EXCLUSIVE off
IF NOT USED('person')
USE f:\albat9\person ORDER email IN 0
SELECT person
ELSE
SELECT person
SET ORDER TO email
ENDIF

*THIS.InitSession("albweb")
EnableSessionState = .T.

SEEK UPPER(ALLTRIM(this.username.text))
IF EOF()
* WAIT WINDOW 'Did not find: '+UPPER(ALLTRIM(this.username.text))
this.ErrorDisplay.ShowError("The combination of user name and password could not be found")
* this.loginstatus.text = "Not Logged In"
ELSE
*-------- OK: login successful create a session object
* losession = CREATEOBJECT("wwsession")

IF ALLTRIM(this.userpwd.text) == ALLTRIM(person.pwd)
* this.ErrorDisplay.ShowError(this.username.text+ " FOUND & passord OK")
*------- Set values in global variables
mcurrnum = person.num
---------> Session.SetSessionVar("personnum",person.num)


Potter,

Take a look at the docs. They do explain where stuff goes.

Yes all the samples we build in the training use Session and use InitSession() to set up global sessions.

It's really not very difficult. Use the help file and follow the references when in doubt.

+++ Rick ---


Rick,

The more I read your answers the less I think I know. What and where are "declaration of properties for the page" ?

Do the sample WestWind projects (TimeTrakker etc.) use Session? Maybe if I could see the use in action it would make more sense to me.

Potter


You can also enable session state for individual Page classes by setting

EnableSessionState = .T.

in the declaration of properties for the page. This too fires InitSession() if it hasn't been fired yet.

Along the same lines:

Process.lEnableSessionState = .T.

can also be used (in pages or any other code) to do effectively the same thing.

+++ Rick ---


Thanks - as always. I understand but still don't know which piece of code should get the function OnProcessInit(). I do not have that function anywhere that I can find.

The way my application is structured, the entry point is a page called userin.alb (.alb is the extension I am using). The user provides a valid email address and password and clicks on a login button to start the process. Only if their information is valid will they be allowed to proceed so I guess this is their entry point. Should the function be in this code and be called by the login button click method?

Potter

You don't have to do anything other than making sure you add:

FUNCTION OnProcessInit()
this.InitSession()
* .... any other code that needs to happen at start of every request

into your OnProcessInit() function. This gets the session object initialized for all requests and makes the Session object available.

I'm surprised that you've come this far and have not yet had a need to use the Session object...

+++ Rick ---



Ian,

Thanks. I read the help file sections (several times) and it looks like I can create a session, store data using sessionsetvar and retrieve it later with sessiongetvar.

What I could not figure out was where and how I get the wwsession started. Does it have to go in the WestWind program in c:\wconnect\... or in my code behind segments in c:\inetpub\wwwroot\...?

Potter


Potter... the place to keep user 'global' variables and their data is in the Session... look up the wwSession class in the Help file under Framework Support Classes... review the 'How It Works' topic... there is an explanation of how to utuilize this class... basically, the first time a user logs in and throughout the hit you can place 'global' variable/values in their session... then when they return you re-initialize these variable/values to 'maintain' their state for the logged in user... another way to maintain some state is to utilize a 'License Plate' methodology in the URL, though this is more involved... HTH...

I am still/again confused about this stateless nature of the Web application and in particular scope issues. When the user comes to my site, I force him to login with an e-mail address and password, look them up in a FoxPro table and determine what kind of access they should be allowed. How do I create memory variables or an object that will remain in scope in the various code behind programs throughout the users session? If I create a variable in the top-level Web connection executable, I presume it will remain in scope throughout, but will each individual visiting the website have their own set of these top-level variables?












Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  Rick Strahl
  Arnold
  Apr 24, 2012 @ 01:47pm

Either one will work.

+++ Rick ---


Potter
I thinks it's This.oSession.SetSessionVar("personnum",person.num).......instead of your Session.SetSessionVar("personnum",person.num)...
Hope this helps...
Cheers...
Arnold
---------------------------------------------------


Rick,

I find it very difficult. I have read and Read the documentation and all of the methods you have suggested in previous responses with no luck. The first interaction a user has is when they fill in an email address and a password and click the login button. Shown below is the code that fires on from that button click. At the line "Session.SetSession.... I get the error "Session is not an object" (arrow added)

FUNCTION userloginbutton_click()
SET EXCLUSIVE off
IF NOT USED('person')
USE f:\albat9\person ORDER email IN 0
SELECT person
ELSE
SELECT person
SET ORDER TO email
ENDIF

*THIS.InitSession("albweb")
EnableSessionState = .T.

SEEK UPPER(ALLTRIM(this.username.text))
IF EOF()
* WAIT WINDOW 'Did not find: '+UPPER(ALLTRIM(this.username.text))
this.ErrorDisplay.ShowError("The combination of user name and password could not be found")
* this.loginstatus.text = "Not Logged In"
ELSE
*-------- OK: login successful create a session object
* losession = CREATEOBJECT("wwsession")

IF ALLTRIM(this.userpwd.text) == ALLTRIM(person.pwd)
* this.ErrorDisplay.ShowError(this.username.text+ " FOUND & passord OK")
*------- Set values in global variables
mcurrnum = person.num
---------> Session.SetSessionVar("personnum",person.num)


Potter,

Take a look at the docs. They do explain where stuff goes.

Yes all the samples we build in the training use Session and use InitSession() to set up global sessions.

It's really not very difficult. Use the help file and follow the references when in doubt.

+++ Rick ---


Rick,

The more I read your answers the less I think I know. What and where are "declaration of properties for the page" ?

Do the sample WestWind projects (TimeTrakker etc.) use Session? Maybe if I could see the use in action it would make more sense to me.

Potter


You can also enable session state for individual Page classes by setting

EnableSessionState = .T.

in the declaration of properties for the page. This too fires InitSession() if it hasn't been fired yet.

Along the same lines:

Process.lEnableSessionState = .T.

can also be used (in pages or any other code) to do effectively the same thing.

+++ Rick ---


Thanks - as always. I understand but still don't know which piece of code should get the function OnProcessInit(). I do not have that function anywhere that I can find.

The way my application is structured, the entry point is a page called userin.alb (.alb is the extension I am using). The user provides a valid email address and password and clicks on a login button to start the process. Only if their information is valid will they be allowed to proceed so I guess this is their entry point. Should the function be in this code and be called by the login button click method?

Potter

You don't have to do anything other than making sure you add:

FUNCTION OnProcessInit()
this.InitSession()
* .... any other code that needs to happen at start of every request

into your OnProcessInit() function. This gets the session object initialized for all requests and makes the Session object available.

I'm surprised that you've come this far and have not yet had a need to use the Session object...

+++ Rick ---



Ian,

Thanks. I read the help file sections (several times) and it looks like I can create a session, store data using sessionsetvar and retrieve it later with sessiongetvar.

What I could not figure out was where and how I get the wwsession started. Does it have to go in the WestWind program in c:\wconnect\... or in my code behind segments in c:\inetpub\wwwroot\...?

Potter


Potter... the place to keep user 'global' variables and their data is in the Session... look up the wwSession class in the Help file under Framework Support Classes... review the 'How It Works' topic... there is an explanation of how to utuilize this class... basically, the first time a user logs in and throughout the hit you can place 'global' variable/values in their session... then when they return you re-initialize these variable/values to 'maintain' their state for the logged in user... another way to maintain some state is to utilize a 'License Plate' methodology in the URL, though this is more involved... HTH...

I am still/again confused about this stateless nature of the Web application and in particular scope issues. When the user comes to my site, I force him to login with an e-mail address and password, look them up in a FoxPro table and determine what kind of access they should be allowed. How do I create memory variables or an object that will remain in scope in the various code behind programs throughout the users session? If I create a variable in the top-level Web connection executable, I presume it will remain in scope throughout, but will each individual visiting the website have their own set of these top-level variables?















Rick Strahl
West Wind Technologies

Making waves on the Web

from Maui, Hawaii
Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  Rick Strahl
  Potter Orr
  Apr 24, 2012 @ 01:47pm
Potter,

Seriously if you are using Sessions you wil likely need it in more than one page, so save yourself some hassle and implement InitSession() in the Process class's OnProcessInit(). You can do it there once then forget about it and just use Session in every page.


FUNCTION OnProcessInit()

this.InitSession()
*... other code that runs on every request.

ENDFUNCTION

Look at the time trakker example it does this and more (authentication configuration) in the OnProcessInit().

+++ RIck ---


Rick,

I find it very difficult. I have read and Read the documentation and all of the methods you have suggested in previous responses with no luck. The first interaction a user has is when they fill in an email address and a password and click the login button. Shown below is the code that fires on from that button click. At the line "Session.SetSession.... I get the error "Session is not an object" (arrow added)

FUNCTION userloginbutton_click()
SET EXCLUSIVE off
IF NOT USED('person')
USE f:\albat9\person ORDER email IN 0
SELECT person
ELSE
SELECT person
SET ORDER TO email
ENDIF

*THIS.InitSession("albweb")
EnableSessionState = .T.

SEEK UPPER(ALLTRIM(this.username.text))
IF EOF()
* WAIT WINDOW 'Did not find: '+UPPER(ALLTRIM(this.username.text))
this.ErrorDisplay.ShowError("The combination of user name and password could not be found")
* this.loginstatus.text = "Not Logged In"
ELSE
*-------- OK: login successful create a session object
* losession = CREATEOBJECT("wwsession")

IF ALLTRIM(this.userpwd.text) == ALLTRIM(person.pwd)
* this.ErrorDisplay.ShowError(this.username.text+ " FOUND & passord OK")
*------- Set values in global variables
mcurrnum = person.num
---------> Session.SetSessionVar("personnum",person.num)


Potter,

Take a look at the docs. They do explain where stuff goes.

Yes all the samples we build in the training use Session and use InitSession() to set up global sessions.

It's really not very difficult. Use the help file and follow the references when in doubt.

+++ Rick ---


Rick,

The more I read your answers the less I think I know. What and where are "declaration of properties for the page" ?

Do the sample WestWind projects (TimeTrakker etc.) use Session? Maybe if I could see the use in action it would make more sense to me.

Potter


You can also enable session state for individual Page classes by setting

EnableSessionState = .T.

in the declaration of properties for the page. This too fires InitSession() if it hasn't been fired yet.

Along the same lines:

Process.lEnableSessionState = .T.

can also be used (in pages or any other code) to do effectively the same thing.

+++ Rick ---


Thanks - as always. I understand but still don't know which piece of code should get the function OnProcessInit(). I do not have that function anywhere that I can find.

The way my application is structured, the entry point is a page called userin.alb (.alb is the extension I am using). The user provides a valid email address and password and clicks on a login button to start the process. Only if their information is valid will they be allowed to proceed so I guess this is their entry point. Should the function be in this code and be called by the login button click method?

Potter

You don't have to do anything other than making sure you add:

FUNCTION OnProcessInit()
this.InitSession()
* .... any other code that needs to happen at start of every request

into your OnProcessInit() function. This gets the session object initialized for all requests and makes the Session object available.

I'm surprised that you've come this far and have not yet had a need to use the Session object...

+++ Rick ---



Ian,

Thanks. I read the help file sections (several times) and it looks like I can create a session, store data using sessionsetvar and retrieve it later with sessiongetvar.

What I could not figure out was where and how I get the wwsession started. Does it have to go in the WestWind program in c:\wconnect\... or in my code behind segments in c:\inetpub\wwwroot\...?

Potter


Potter... the place to keep user 'global' variables and their data is in the Session... look up the wwSession class in the Help file under Framework Support Classes... review the 'How It Works' topic... there is an explanation of how to utuilize this class... basically, the first time a user logs in and throughout the hit you can place 'global' variable/values in their session... then when they return you re-initialize these variable/values to 'maintain' their state for the logged in user... another way to maintain some state is to utilize a 'License Plate' methodology in the URL, though this is more involved... HTH...

I am still/again confused about this stateless nature of the Web application and in particular scope issues. When the user comes to my site, I force him to login with an e-mail address and password, look them up in a FoxPro table and determine what kind of access they should be allowed. How do I create memory variables or an object that will remain in scope in the various code behind programs throughout the users session? If I create a variable in the top-level Web connection executable, I presume it will remain in scope throughout, but will each individual visiting the website have their own set of these top-level variables?














Rick Strahl
West Wind Technologies

Making waves on the Web

from Maui, Hawaii
Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  n/a
  Rick Strahl
  Apr 29, 2012 @ 01:44pm
Rick,

I just don’t get it. I have read all of your emails over and over and read the documentation many times. I seem to have 2 main problems.

1. I don’t know where the function OnProcessInit() belongs. Does it go in the code I compile then run to put up the Web Connection box?
2. What does this.InitSession() create? Should it create an object called “Session” ? If it does can I then call the methods of Session from anywhere?

Potter


Potter,

Seriously if you are using Sessions you wil likely need it in more than one page, so save yourself some hassle and implement InitSession() in the Process class's OnProcessInit(). You can do it there once then forget about it and just use Session in every page.


FUNCTION OnProcessInit()

this.InitSession()
*... other code that runs on every request.

ENDFUNCTION

Look at the time trakker example it does this and more (authentication configuration) in the OnProcessInit().

+++ RIck ---


Rick,

I find it very difficult. I have read and Read the documentation and all of the methods you have suggested in previous responses with no luck. The first interaction a user has is when they fill in an email address and a password and click the login button. Shown below is the code that fires on from that button click. At the line "Session.SetSession.... I get the error "Session is not an object" (arrow added)

FUNCTION userloginbutton_click()
SET EXCLUSIVE off
IF NOT USED('person')
USE f:\albat9\person ORDER email IN 0
SELECT person
ELSE
SELECT person
SET ORDER TO email
ENDIF

*THIS.InitSession("albweb")
EnableSessionState = .T.

SEEK UPPER(ALLTRIM(this.username.text))
IF EOF()
* WAIT WINDOW 'Did not find: '+UPPER(ALLTRIM(this.username.text))
this.ErrorDisplay.ShowError("The combination of user name and password could not be found")
* this.loginstatus.text = "Not Logged In"
ELSE
*-------- OK: login successful create a session object
* losession = CREATEOBJECT("wwsession")

IF ALLTRIM(this.userpwd.text) == ALLTRIM(person.pwd)
* this.ErrorDisplay.ShowError(this.username.text+ " FOUND & passord OK")
*------- Set values in global variables
mcurrnum = person.num
---------> Session.SetSessionVar("personnum",person.num)


Potter,

Take a look at the docs. They do explain where stuff goes.

Yes all the samples we build in the training use Session and use InitSession() to set up global sessions.

It's really not very difficult. Use the help file and follow the references when in doubt.

+++ Rick ---


Rick,

The more I read your answers the less I think I know. What and where are "declaration of properties for the page" ?

Do the sample WestWind projects (TimeTrakker etc.) use Session? Maybe if I could see the use in action it would make more sense to me.

Potter


You can also enable session state for individual Page classes by setting

EnableSessionState = .T.

in the declaration of properties for the page. This too fires InitSession() if it hasn't been fired yet.

Along the same lines:

Process.lEnableSessionState = .T.

can also be used (in pages or any other code) to do effectively the same thing.

+++ Rick ---


Thanks - as always. I understand but still don't know which piece of code should get the function OnProcessInit(). I do not have that function anywhere that I can find.

The way my application is structured, the entry point is a page called userin.alb (.alb is the extension I am using). The user provides a valid email address and password and clicks on a login button to start the process. Only if their information is valid will they be allowed to proceed so I guess this is their entry point. Should the function be in this code and be called by the login button click method?

Potter

You don't have to do anything other than making sure you add:

FUNCTION OnProcessInit()
this.InitSession()
* .... any other code that needs to happen at start of every request

into your OnProcessInit() function. This gets the session object initialized for all requests and makes the Session object available.

I'm surprised that you've come this far and have not yet had a need to use the Session object...

+++ Rick ---



Ian,

Thanks. I read the help file sections (several times) and it looks like I can create a session, store data using sessionsetvar and retrieve it later with sessiongetvar.

What I could not figure out was where and how I get the wwsession started. Does it have to go in the WestWind program in c:\wconnect\... or in my code behind segments in c:\inetpub\wwwroot\...?

Potter


Potter... the place to keep user 'global' variables and their data is in the Session... look up the wwSession class in the Help file under Framework Support Classes... review the 'How It Works' topic... there is an explanation of how to utuilize this class... basically, the first time a user logs in and throughout the hit you can place 'global' variable/values in their session... then when they return you re-initialize these variable/values to 'maintain' their state for the logged in user... another way to maintain some state is to utilize a 'License Plate' methodology in the URL, though this is more involved... HTH...

I am still/again confused about this stateless nature of the Web application and in particular scope issues. When the user comes to my site, I force him to login with an e-mail address and password, look them up in a FoxPro table and determine what kind of access they should be allowed. How do I create memory variables or an object that will remain in scope in the various code behind programs throughout the users session? If I create a variable in the top-level Web connection executable, I presume it will remain in scope throughout, but will each individual visiting the website have their own set of these top-level variables?














Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  Rick Strahl
  Potter Orr
  Apr 29, 2012 @ 02:26pm
Potter,

I'm sorry you can't figure this out, but I don't know how to explain it any simpler than this, since this is a really simple concept.

One more time:


  • Open your Process class (YourProcess.prg)
  • Find or create an OnProcessInit() method
  • Add this.InitSession() into this method
  • Done - all your requests now have Session state

If you created your project or separate process class via the Wizard the code is already there, but it's commented out.

+++ Rick ---



Rick,

I just don’t get it. I have read all of your emails over and over and read the documentation many times. I seem to have 2 main problems.

1. I don’t know where the function OnProcessInit() belongs. Does it go in the code I compile then run to put up the Web Connection box?
2. What does this.InitSession() create? Should it create an object called “Session” ? If it does can I then call the methods of Session from anywhere?

Potter


Potter,

Seriously if you are using Sessions you wil likely need it in more than one page, so save yourself some hassle and implement InitSession() in the Process class's OnProcessInit(). You can do it there once then forget about it and just use Session in every page.


FUNCTION OnProcessInit()

this.InitSession()
*... other code that runs on every request.

ENDFUNCTION

Look at the time trakker example it does this and more (authentication configuration) in the OnProcessInit().

+++ RIck ---


Rick,

I find it very difficult. I have read and Read the documentation and all of the methods you have suggested in previous responses with no luck. The first interaction a user has is when they fill in an email address and a password and click the login button. Shown below is the code that fires on from that button click. At the line "Session.SetSession.... I get the error "Session is not an object" (arrow added)

FUNCTION userloginbutton_click()
SET EXCLUSIVE off
IF NOT USED('person')
USE f:\albat9\person ORDER email IN 0
SELECT person
ELSE
SELECT person
SET ORDER TO email
ENDIF

*THIS.InitSession("albweb")
EnableSessionState = .T.

SEEK UPPER(ALLTRIM(this.username.text))
IF EOF()
* WAIT WINDOW 'Did not find: '+UPPER(ALLTRIM(this.username.text))
this.ErrorDisplay.ShowError("The combination of user name and password could not be found")
* this.loginstatus.text = "Not Logged In"
ELSE
*-------- OK: login successful create a session object
* losession = CREATEOBJECT("wwsession")

IF ALLTRIM(this.userpwd.text) == ALLTRIM(person.pwd)
* this.ErrorDisplay.ShowError(this.username.text+ " FOUND & passord OK")
*------- Set values in global variables
mcurrnum = person.num
---------> Session.SetSessionVar("personnum",person.num)


Potter,

Take a look at the docs. They do explain where stuff goes.

Yes all the samples we build in the training use Session and use InitSession() to set up global sessions.

It's really not very difficult. Use the help file and follow the references when in doubt.

+++ Rick ---


Rick,

The more I read your answers the less I think I know. What and where are "declaration of properties for the page" ?

Do the sample WestWind projects (TimeTrakker etc.) use Session? Maybe if I could see the use in action it would make more sense to me.

Potter


You can also enable session state for individual Page classes by setting

EnableSessionState = .T.

in the declaration of properties for the page. This too fires InitSession() if it hasn't been fired yet.

Along the same lines:

Process.lEnableSessionState = .T.

can also be used (in pages or any other code) to do effectively the same thing.

+++ Rick ---


Thanks - as always. I understand but still don't know which piece of code should get the function OnProcessInit(). I do not have that function anywhere that I can find.

The way my application is structured, the entry point is a page called userin.alb (.alb is the extension I am using). The user provides a valid email address and password and clicks on a login button to start the process. Only if their information is valid will they be allowed to proceed so I guess this is their entry point. Should the function be in this code and be called by the login button click method?

Potter

You don't have to do anything other than making sure you add:

FUNCTION OnProcessInit()
this.InitSession()
* .... any other code that needs to happen at start of every request

into your OnProcessInit() function. This gets the session object initialized for all requests and makes the Session object available.

I'm surprised that you've come this far and have not yet had a need to use the Session object...

+++ Rick ---



Ian,

Thanks. I read the help file sections (several times) and it looks like I can create a session, store data using sessionsetvar and retrieve it later with sessiongetvar.

What I could not figure out was where and how I get the wwsession started. Does it have to go in the WestWind program in c:\wconnect\... or in my code behind segments in c:\inetpub\wwwroot\...?

Potter


Potter... the place to keep user 'global' variables and their data is in the Session... look up the wwSession class in the Help file under Framework Support Classes... review the 'How It Works' topic... there is an explanation of how to utuilize this class... basically, the first time a user logs in and throughout the hit you can place 'global' variable/values in their session... then when they return you re-initialize these variable/values to 'maintain' their state for the logged in user... another way to maintain some state is to utilize a 'License Plate' methodology in the URL, though this is more involved... HTH...

I am still/again confused about this stateless nature of the Web application and in particular scope issues. When the user comes to my site, I force him to login with an e-mail address and password, look them up in a FoxPro table and determine what kind of access they should be allowed. How do I create memory variables or an object that will remain in scope in the various code behind programs throughout the users session? If I create a variable in the top-level Web connection executable, I presume it will remain in scope throughout, but will each individual visiting the website have their own set of these top-level variables?

















Rick Strahl
West Wind Technologies

Making waves on the Web

from Maui, Hawaii
Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  n/a
  Rick Strahl
  Apr 29, 2012 @ 06:45pm
Rick,

Your last try seems to have worked. I was looking in the wrong .prg Finally I looked in the other generated prg in c:\wconnect and found the commented out onprocessinit. Now that this is done, I will see if I can use the Session.

Thanks for all your help,

Potter


Potter,

I'm sorry you can't figure this out, but I don't know how to explain it any simpler than this, since this is a really simple concept.

One more time:


  • Open your Process class (YourProcess.prg)
  • Find or create an OnProcessInit() method
  • Add this.InitSession() into this method
  • Done - all your requests now have Session state

If you created your project or separate process class via the Wizard the code is already there, but it's commented out.

+++ Rick ---



Rick,

I just don’t get it. I have read all of your emails over and over and read the documentation many times. I seem to have 2 main problems.

1. I don’t know where the function OnProcessInit() belongs. Does it go in the code I compile then run to put up the Web Connection box?
2. What does this.InitSession() create? Should it create an object called “Session” ? If it does can I then call the methods of Session from anywhere?

Potter


Potter,

Seriously if you are using Sessions you wil likely need it in more than one page, so save yourself some hassle and implement InitSession() in the Process class's OnProcessInit(). You can do it there once then forget about it and just use Session in every page.


FUNCTION OnProcessInit()

this.InitSession()
*... other code that runs on every request.

ENDFUNCTION

Look at the time trakker example it does this and more (authentication configuration) in the OnProcessInit().

+++ RIck ---


Rick,

I find it very difficult. I have read and Read the documentation and all of the methods you have suggested in previous responses with no luck. The first interaction a user has is when they fill in an email address and a password and click the login button. Shown below is the code that fires on from that button click. At the line "Session.SetSession.... I get the error "Session is not an object" (arrow added)

FUNCTION userloginbutton_click()
SET EXCLUSIVE off
IF NOT USED('person')
USE f:\albat9\person ORDER email IN 0
SELECT person
ELSE
SELECT person
SET ORDER TO email
ENDIF

*THIS.InitSession("albweb")
EnableSessionState = .T.

SEEK UPPER(ALLTRIM(this.username.text))
IF EOF()
* WAIT WINDOW 'Did not find: '+UPPER(ALLTRIM(this.username.text))
this.ErrorDisplay.ShowError("The combination of user name and password could not be found")
* this.loginstatus.text = "Not Logged In"
ELSE
*-------- OK: login successful create a session object
* losession = CREATEOBJECT("wwsession")

IF ALLTRIM(this.userpwd.text) == ALLTRIM(person.pwd)
* this.ErrorDisplay.ShowError(this.username.text+ " FOUND & passord OK")
*------- Set values in global variables
mcurrnum = person.num
---------> Session.SetSessionVar("personnum",person.num)


Potter,

Take a look at the docs. They do explain where stuff goes.

Yes all the samples we build in the training use Session and use InitSession() to set up global sessions.

It's really not very difficult. Use the help file and follow the references when in doubt.

+++ Rick ---


Rick,

The more I read your answers the less I think I know. What and where are "declaration of properties for the page" ?

Do the sample WestWind projects (TimeTrakker etc.) use Session? Maybe if I could see the use in action it would make more sense to me.

Potter


You can also enable session state for individual Page classes by setting

EnableSessionState = .T.

in the declaration of properties for the page. This too fires InitSession() if it hasn't been fired yet.

Along the same lines:

Process.lEnableSessionState = .T.

can also be used (in pages or any other code) to do effectively the same thing.

+++ Rick ---


Thanks - as always. I understand but still don't know which piece of code should get the function OnProcessInit(). I do not have that function anywhere that I can find.

The way my application is structured, the entry point is a page called userin.alb (.alb is the extension I am using). The user provides a valid email address and password and clicks on a login button to start the process. Only if their information is valid will they be allowed to proceed so I guess this is their entry point. Should the function be in this code and be called by the login button click method?

Potter

You don't have to do anything other than making sure you add:

FUNCTION OnProcessInit()
this.InitSession()
* .... any other code that needs to happen at start of every request

into your OnProcessInit() function. This gets the session object initialized for all requests and makes the Session object available.

I'm surprised that you've come this far and have not yet had a need to use the Session object...

+++ Rick ---



Ian,

Thanks. I read the help file sections (several times) and it looks like I can create a session, store data using sessionsetvar and retrieve it later with sessiongetvar.

What I could not figure out was where and how I get the wwsession started. Does it have to go in the WestWind program in c:\wconnect\... or in my code behind segments in c:\inetpub\wwwroot\...?

Potter


Potter... the place to keep user 'global' variables and their data is in the Session... look up the wwSession class in the Help file under Framework Support Classes... review the 'How It Works' topic... there is an explanation of how to utuilize this class... basically, the first time a user logs in and throughout the hit you can place 'global' variable/values in their session... then when they return you re-initialize these variable/values to 'maintain' their state for the logged in user... another way to maintain some state is to utilize a 'License Plate' methodology in the URL, though this is more involved... HTH...

I am still/again confused about this stateless nature of the Web application and in particular scope issues. When the user comes to my site, I force him to login with an e-mail address and password, look them up in a FoxPro table and determine what kind of access they should be allowed. How do I create memory variables or an object that will remain in scope in the various code behind programs throughout the users session? If I create a variable in the top-level Web connection executable, I presume it will remain in scope throughout, but will each individual visiting the website have their own set of these top-level variables?

















Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  VFPJCOOK
  Rick Strahl
  Mar 30, 2020 @ 02:21pm

Rick, Just doing a lot of reading about sessions in trying to figure out how much of my data can be pulled once for all users and once per a particular user, so 2 different sets of data.

In my desktop app when the users selects POS from the menu, I pull a lot of data about product (things sold) that apply regardless which person (inmate) is being sold to. That data is persistent until POS is exited. Once into POS, there is a screen for entry on an id for the person being sold to. I look up information about that person. I then merge the product and person data, producing data that is persistent while ringing up the sale.

Depending on the amount of data which varies tremendously per customer site, it can take approximately 7 seconds to pull the product data and then 5 seconds to pull the person data and merge it with the product data to produce data that is persistent while the sale is being rung up. This is not an issue because the product data is only pulled once when you go into the POS feature (theoretically once per day) and the person data is once pulled per sale. While you are ringing up a sale, everything is instantaneous as there are no database hits.

For the sake of including the "whole" picture, I should mention, because other things could have debited the person's account since the sale was begun, and they may no longer have enough money to make the purchase, the "person" data is pulled once again so it can take 5 seconds to save a sale and print a receipt, also acceptable.

One more big picture should be mentioned: If you go to the grocery store, while the cashier is ringing up your sale/scanning product, she does not know or care how much money you have because you are asked to pay when she is finished. My POS is different. Everytime a product is added to your sale (on the website that would be every quantity change), my app determines if you have enough money to add that item and does not allow entry if you do not. There are a lot more things it checks. If you are diabetic and try to scan a Snickers bar it will stop and not allow entry, etc. (Find me a vertical market for that and we will be millionaires). My point is I want this part to work the same for my website order entry. I believe that is very important. That means I basically need this same global/product and session/"merged product and person data", for my website.

Finally my question and I apologize for all the reading to get to this: I feel like I would need a session record for the global/product data and a separate session record for the "merged product and person data". Just checking to ensure that is a possibility and makes sense.

Also, I noticed a lot of posts about using a global session to store the handle for a SQL server connection. I use native foxpro but am wondering if the same concept applies to opening my tables and views databases once and maybe even to a object reference to a REST service that would do all the data handling and maybe even the validations performed while ringing up a sale.

Your thoughts appreciated, John

Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  Rick Strahl
  VFPJCOOK
  Mar 30, 2020 @ 03:37pm

John,

You might want to break down your questions into more specific ones, rather than these long ones that cover a whole bunch of different issues. That makes it really hard to give you an answer.

Here are few points:

Session State

You can use Session state to store any type of data (as string via serialization) you need including nested and array sub data. You can serialize this data at the end of an 'unfinished' request and then deserialize it on the next request to pick up where you left off.

It's not super efficient to do this (because FoxPro Memo Bloat and Serialization overhead) but it is one way to carry request data across multiple requests, without writing data into application tables before the data is completed.

Status Updates

You can mix this server based HTML approach with client side JavaScript AJAX calls to retrieve small bits information for validation. Like your price check, quantity check, the Diabetic rule check etc. When a page loads or when some other action occurs you can make a small service request to the server and retrieve the validation result that can let you decide on whether a transaction is allowed for example.

Or alternately if each step of the way is a new page you can check when the page loads on the server to decide that as well. There are options...

Which One?

Think of the server based approach like a Wizard with Page1, Page2, Page3 where after each page but the last you save the entire state of your transaction in a Session object.

You can still use this approach with AJAX callbacks - those are just simple things to validate data and can update the UI either hiding stuff, or marking up stuff as a warning for example.

You have choices and there are no single answers here.

My suggestion is this:

If you want to do the server based 'Wizard' style and serialization into Session approach start with that and figure out what your 'Page' or 'Operation' boundaries need to be. What operations need to be performed on your screen(s) and what needs to happen in order to preserve and restore the state between clicking the button and bringing back a form that has of its state intact.

As I mentioned in our earlier session, if you want a more interactive experience then a client side JavaScript application using one of the SPA frameworks is a better approach. If you want a more page based approach then using the server side code is the way to go.

Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  VFPJCOOK
  Rick Strahl
  Apr 1, 2020 @ 02:04pm

Rick, quick simple question (I hope). I am trying to see the web connection framework code. I can not find it. I want to look at wwc_process. I would think it is in a vcx library but can not find it.

Thanks, john

Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  Rick Strahl
  VFPJCOOK
  Apr 1, 2020 @ 02:43pm

It's in wwprocess.prg...

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  VFPJCOOK
  Rick Strahl
  Apr 1, 2020 @ 04:14pm

Thanks for that. OK, I have classed and subclassed my self into oblivion. I believe you can really speed me up by answering this:

Using the webdemo project, exactly where would I put code to open the customer table so that it would be open and available for use throughout the life of the server? So, immediately after all the configuration and pathing is set until the server is exited or killed.

Hope that makes sense? John

Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  Rick Strahl
  VFPJCOOK
  Apr 2, 2020 @ 04:24pm

Code that runs once on startup should go into WebDemoMain.prg in WebDemoServer::Load().

FWIW - I think that's not really a good way to do this. The way to do it IMHO, is write defensive code that checks to see if the table is open:

IF !USED("Customers")
   USE Customers in 0 ALIAS Customers
   SELECT Customers   
ENDIF

If you're using the business object that pretty much happens on its own anyway.

Then just don't close the table. But using the above code will ensure that the table will always be opened even if it was accidentally closed. Assuming it's always open is too difficult to enforce to make that realistic IMHO.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  VFPJCOOK
  Rick Strahl
  Apr 17, 2020 @ 10:41am

Hi Rick, Just getting back to this project. I am thinking I will use my web service for application database queries and updates. That is the web service you helped me develop. The web service will need some modifications but it was designed to "pull an inmates current balance" and to "post a sale" so it is conceptually already designed to do the database functionality needed for my website. Because it will need some modifications to accomodate the website activity, and because those modifications could mean adding new functions/methods, and because that means recompiling the C# program (something I have not ever needed to do), I want to ask if there would be benefits to a developing a REST service vs using my ASP.NET web service for this purpose? Perhaps a REST service would be faster or easier to modify and maintain? Just looking for your opinion.

Thanks, John

Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  Rick Strahl
  VFPJCOOK
  Apr 17, 2020 @ 01:48pm

If I recall the point of the ASP.NET Service was to provide SOAP functionality to your clients. There's no good facility in FoxPro to provide SOAP services any longer and it's a very complex thing to build something that works well there, which is why we did it at the time in ASP.NET.

If you want to build a REST service, you can use Web Connection to do that. REST services are really whatever you make them - there are no hard and fast rules, it's mostly recommendations. You ask for data in and you return data out - it's pretty simple. And you can do that with FoxPro that you know rather than doing it in .NET.

The downside is that if you want to host this you need to have an environment that's configured to run Web Connection, which pretty much means you need to use a Virtual Windows Machine while ASP.NET applications can be hosted much more easily just about anywhere. Although even with your existing service additional system services are needed for the FoxPro OleDb driver I believe we used which may not exist on newer Windows machines without explicit installation.

IAC - yes you can use REST services and it is an option that lets you continue to use FoxPro. But realize that it'll provide a different interface (non-SOAP) than your old .NET based service.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  VFPJCOOK
  Rick Strahl
  Apr 18, 2020 @ 07:26am

Well, I really do not recall WHY we chose to provide SOAP functionality to my clients but let's assume it was per their request. My ASP.NET service does work well and it does contain a LOT of code which I had rather not repeat. Because you are a bit versed in my app, I will go ahead and say the ASP.NET service provides just about all the data handling (querying of and posting to my app's database) that will be required by my website with one exception. The ASP.NET service is only used to ring up sales where there is always only one item sold (1 line item per sale). The website will be used to ring up sales with many line items in a single sale.

That aside, I believe I will assume at this point I am going to use the ASP.NET service to do the data handling for my website. FYI, no Foxpro OleDb driver involved. My ASP.NET service is one of my VFExpress apps compiled to a Multi threaded DLL. I have developed code using the WW Proxy Generator that I use to access my ASP.NET service for instances where a customer calls wanting me to ensure my web service is functioning properly.

Here is the big picture for how I believe this would work:

In WebDemoMain.prg at the end of the WebdemoServer :: OnLoad method, I would add code to instanciate and get an object reference to my ASP.NET service (which would be running on the same cloud server if that matters). I would store that reference in a "global" (to my website's web server), property.

I would immediately access the ASP.NET service to pull data that is persistent through the life of my web server and store that data in cursors, arrays and properties (also global).

One last thing to do in OnLoad/global: As the website gets hits (makes sales), I will place those sales/line items in a global cursor probably using the session id as a key to the records for a particular session, so all recs for session 1 have a key value of 1, all recs for session 2 have a key value of 2, etc. So I would create that empty global cursor (call it mySessionDataCursor) here in OnLoad.

In my webprocess methods I would get the requests session id using WC features and be able to access the data in loserver.mySessionDataCursor to do whatever my website needs to do.

I would make calls to my ASP.NET service to start a session (first request would be to get an inmate's info) and to save the sales.

I have left out a lot of details but am I saying anything that raises a red flag with you?

Thanks, John

Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  VFPJCOOK
  VFPJCOOK
  Apr 23, 2020 @ 03:08pm

Hi Rick, Did you have a chance to read my latest question in this thread? Perhaps my question was so WRONG you just did not want to tell me? If so, please do let me know. Thank you for your time, john

Gravatar is a globally recognized avatar based on your email address. Re: Scope of variables
  Rick Strahl
  VFPJCOOK
  Apr 27, 2020 @ 08:24pm

Did you have a chance to read my latest question in this thread? Perhaps my question was so WRONG you just did not want to tell me? If so, please do let me know. Thank you for your time, john

John, the problem is that you write these novels for these posts with multiple issues and you keep tacking it onto the same long thread that has long since crept out of the scope of the topic. Answering these posts is time-consuming and I don't always have the time to address them here especially since they are not really directly related to the tooling that's being supported here.

We're talking about a very specific scenario for your environment and we're basically what amounts to a high level architecture discussion. Usually I'm not opposed to doing that here, but in the context of this message and the scope creep I've been letting it creep off the list.

So, maybe start a new thread and reformulate what you want to ask a little more concisely and we can see about getting the answers you're looking for.

Thanks,

+++ Rick ---

© 1996-2020