If I use a protected variable, does the variable exist for the whole web application or does it get removed when the user move to other page by get or post? I do know that it is not accessible in other pages unless I use static variable, but I am curious as to if it exists for the whole application. Please let me know!
when you move to other page and return, a new instance of your page class will be created and so all non static variables will be reset.
The value will be valid in a one request process life time (starts with request start and ends with request end)
making a variable protected, just means that this variable is access-able in inherited class. for example in asp.net you can use it in inherited class like inside your markup (because it inherits code behind class)
this is the meaning of protected variable
if you want to keep a value saved between pages you can use one of these items depending on your requirement :
Cookie
Query String
Session States
Application States
Cache
and ViewState keeps state variable between postback in a same page or control while it is not redirected to another page.
protected keyword does not determine how long a variable exists nor does it determine whether it will be available in the next post back.
What you are probably looking for is state management.
Take a look at this webpage to see how you can maintain state between post backs, different pages etc.
Also take a look at this page to determine which state management feature to use in which situation.
In general, "page" variables only live through the duration of the request. If your variable is static, there will only be one instance of the variable for all the requests until the app domain unloads.
If your variable is private or protected, no other classes will have access to it.
Your question, however, seems a little strange. What's your concern?
Related
I've created an asp.net page for work that allows customers to look up users in AD, and then request to have them added as delegates to Rightfax numbers, which can also be searched for. Rightnow I'm storing public variables used by the back end and front end of the project in a CurrentSession class inherited by the pages thats supposed to be unique to each user, but I'm still seeing occasional issues where variables will 'bleed' from one session to another. Sometimes I'll go to the page and the list of AD users is already populated with users from another session\user.
I'm wondering what the best method is for storing variables in this scenario. Should I be using cookies rather than a current session class? Are there any good guides/tutorials that go over variable management for asp.net pages? I'm typically a desktop developer so I'm not particularly familiar with this kind of issue.
the whole jump to the web, and that of session managment, or varible managment is a huge topic. And it is often a challenge, since the concpets are very different then desktop.
So, I mean, when a user clicks a button, the web page is posted up to the server. The page is found, loaded, variables start from scratch. Code behind runs, page is sent back down to client AND THE PAGE SERVER SIDE IS TOSSED out!
So, the above is a new challenge, due to that so called "state-less" nature of web pages.
As for session bleeing to other users? Hum, that should not occur. However, session() can be VERY fragle. Due to time outs, due to some execution error in code, the app pool can and will often re-start.
So, I strong recommend that you run the script and turn on SQL servre based sesison management. Once done, then session() becomes bullet proof - and always works.
As for values bleeding to other users? No way - I not seen that.
(of course, you did not mention or note what authentication provider you are using (or even if users have to logon).
However, while I OFTEN use session, and even to pass values from one page to the next? (absolute hate parameters in the URL - messy and often security risk if things like PK id etc. are included)).
However, some big sites say like amazon use parameters and values in the URL a lot. They do this since then the server side does not get over-loaded and have to keep track or hold those values. However, unless you building the next facebook, or huge + high volume web site, then session() is quite much the standard approch to keep values active for your code.
However, lets assume we toss up a grid, and the user selects that product?
We set in session() say that PK id, and hten jump to the next page say to buy that house?
Well, now if you open a new tab - even a different browser, launch that grid, select a house and jump to the page to display that information? You can't use session since as noted it will overwrite the values in the other page.
So, you can try and build a bunch of fancy classes and all kinds of handstands, but I just simply transfer the session() values to ViewState.
ViewState is per page, and session() is global to that one user.
So, if I need 10 variables and value for a given part of the application, say like this:
<Serializable>
Public Class clsProjectInfo
Public ContactID As Integer = 0
Public ContactGeneralID As Integer = 0
Public PortalComp As String = ""
Public ProjectHeaderID As Integer = 0
Public QuoteNum As Integer = 0
Public UploadGroup As Integer = 0
Public txtNotes As String = ""
Public ProofID As Integer = 0
End Class
So say in the page that we select the project - setup a whole buch of values?
Then the above var will be in session(), but ONLY for pasing to the next page.
So the project view page that needs all of the aobve values to work?
The page load code will look like this:
Dim cPinfo As New clsProjectInfo
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsPostBack = False Then
cPinfo = Session("Pinfo")
ViewState("Pinfo") = cPinfo
Else
cPinfo = ViewState("Pinfo")
End If
So we only EVER use session to pass that "bunch of values" to the next page, but always first thing we do is transfer from session() to viewstate. That way if the user opens another tab, or selects a different house in that 2nd browser, jumps to the view details, we only ever used session() to pass the values to the next page, but from that point on, always used ViewState.
Now the above simple idea might not work for all cases but it does for most.
So, don't adopt huge number of session() values, and as always even in desktop, global vars and values should not be required.
So session() for a given user will most certainly often "stomp" on top of other parts of the application. If session() is spilling over between different users? That should not occur, never occur and means as noted something else is going wrong here.
So even for desktop software? Each form, or page or part of the application tend to have and need a set of values. So, I build plane jane simple class as per above. And then you can with great ease pass ONE class thing with the 5-10 variables in it. that way I don't wind up with 50 variables in session() - which is a nightmare from coding point of view (let alone to remember the varaiables). But with above passing the one class, then you just passing ONE thing and you get intel-sense too boot.
And no doubt that group of variables often has to be passed to routine. So beofre above, I often like had to pass like 5-6 values to some function or sub - and what a pan.
So old way:
Call SaveAfterUpload(AjaxFileUpload1, session("QuoteNum", session("ContactID",
session("UploadGroup"), strCleanFile, session("txtNotes"), session("PortalComp")
but now we can go:
Call SaveAfterUpload(AjaxFileUpload1, cPinfo.QuoteNum, cPinfo.ContactID,
cPinfo.UploadGroup, strCleanFile, cPinfo.txtNotes, cPinfo.PortalComp)
But, then again, since we have that class, then above now becomes
Call SaveAfterUpload(AjaxFileUpload1, cPinfo)
So, don't put a truck load of values into session().
Create "groupings" of the values.
And what is even SUPER great?
often some of the client side JavaScript code needs those values.
So, you THEN wind up dropping in a boatload of hidden fields or hidden cnotrols for those values.
But, with the above class? I can pass + have the whole mess client side like this:
cPinfo = ViewState("Pinfo") ' this no doubt occured on page load
' copy Pinfo to browser side
MyUpLoadInfo.Value = JsonConvert.SerializeObject(cPinfo)
MyUpLoadInfo is just a simple asp.net hidden field like this:
<asp:HiddenField ID="MyUpLoadInfo" runat="server" ClientIDMode="Static" />
But, now in place of those 5-6 hidden fields, I have the above cPinfo now for use in the client side.
eg this:
MyUpLoadInfo = document.getElementById("MyUpLoadInfo")
Pinfo = JSON.parse(MyUpLoadInfo.value)
// now I have all values such as
Pinfo.txtNotes
Pinfo.QuoteNum
So, by building that class or set of variables, I can now pass down the WHOLE mess in one shot to the client side, and now my JavaScript code can with great ease use all those variables client side!!
And it turns out that for each section of a typical application?
about 5-10 variables are only required
often they are required client side - and with above we can
Most if not ALL of the routines in that application part need those vars
(including subs and functions, so now we can pass 5-10 values, and we don't
have huge long list of messy parameters in all of those subs and functions).
We can modify the class - add more variables, and the dozen routines now all have that extra variable - yet we don't change the code, or even change the sub/function calls to have that extra new variable in that code.
(and this applies to client side js code if we need/require that group of values for the browser code.).
So we thus don't have huge numbers of global vars.
we don't wind up with a gazillion number of separate session values.
we vast improve the ability to pass those values to subs/functions.
And we even can pass that set of values to the client side with great ease.
So any global var can be in session, but those global vars are NEVER to be used for passing value from page to page and code calls for a given part of your application.
And if you want to support more then one page or browser by the user? Then adopt the standard that on first page load you transfer that session class to viewstate.
I'm working in an ASP.NET (VB) Web Application with Windows/Active Directory Authentication
I am using a module so that I can call public subroutines and functions, and reference variables, without having to instantiate a new object to access them on each page.
Within that module, I have some Public variables that I am using in multiple pages throughout the web application. I've recently realized that the values for these public variables in the module get shared between all users.
THE GOAL:
I want the value for these global variables to be specific to a single user and not shared between all sessions, and I do not want to have to instantiate a new object/class on every page that uses the variable.
THE CATCH:
I don't want to store the value in a client-side variable such as a cookie or session. I want the value to be stored on the SERVER but specific to each client/user.
The only thing I can think to do is setup a global collection/dictionary and store the variables with the authenticated user names, but then I need to have specific functions to get and set the values. While this will work, it requires all the references to these variables on all pages in the application to be updated.
EXAMPLE OF THE PROBLEM:
The below code shows how I am creating the public variable within the module and how the value is being set from one page and used on another. I'd like to continue to use this variable in the same way and share it's value between pages, but the value of the variable needs to NOT be shared between users.
-- MODULE.VB --
Public Module MyMod
Public myVariable as String = ""
End Module
-- MAINPAGE.VB --
Partial Class _Default
Sub Page_Load() Handles MyBase.Load()
myVariable = "HELLO WORLD"
End Sub
End Class
-- NEXTPAGE.VB --
Partial Class _Default
Sub Page_Load() Handles MyBase.Load()
Response.Write(myVariable)
End Sub
End Class
There are a LOT of pages in this application that will need to be manually updated if I have to use my userID-indexed collection solution, so I'm hoping there is a way to simply scope these variables differently or a way to disable the sharing between sessions.
Thanks in advance!
You didn't indicate whether or not the variables need to be persisted across page round trips or whether they are just used within each page's lifecycle.
If they are not persisted across pages, then perhaps the easiest solution is to have all of your pages inherit from a based page class and then move the values from the module into the base page. This way you won't have to change any variable references, only page inheritance.
If you do want to persist the values, completing the above changes makes it much easier to implement. You can then turn the member variables on the base page into properties and embed your user specific caching and fetching in the getter and setter.
For example, instead of:
Public MyVariable As String = ""
You would have something like:
Public Property MyVariable As String
Get
Return GlobalMyVariableCache(UserNameKey)
End Get
Set (Value As String)
GlobalMyVariableCache(UserNameKey) = Value
End Set
End Property
The problem you are coming across is a very common one in web programming. A Module's members are static - meaning there is one instance of them across the entire AppDomain of your application. Every user that accesses these will get the same object - you have already learned this.
Your options are exactly what you described. You could possibly replace the public variable in your module with a property whose getter you write to access a user-specific field in a dictionary (please remember thread safety when writing this getter code).
The much easier solution would be to use the Session. Session values are stored server-side and are user specific. The only thing that get's sent client side is the session key, and if you are using .Net authentication, this is likely already getting sent.
Good luck,
I have 3 dyanmically generated dropdowns in this aspx page. The 2nd and 3rd one are populated as per the selected value of the first one (I've the code for creating the 2nd and 3rd dropdown in 1st one's selectedindexchanged event)
How do I write the code in a such a way that when I traverse back to the page, the dynamic dropdowns retain their selected values?
I'm assuming that what you mean when you say that you "traverse back" to the page is that you navigate to a different page on the site and come back to this page that it's dropdown values will be filled in with what the user selected.
Remember that HTTP is an inherintly statless protocol in that it won't remember data in between postback to the servers. In order to overcome this limitation ASP.NET and other web frameworks use various ways of saving data between request. Currently you are relying on "ViewState" that is stored within the page as a hidden variable called __VIEWSTATE (look at the page source sometime to get an idea of what field looks like) this scope of this hidden variable is when the page first gets loaded and everytime you do a postback to the same page. From your description you probably need a longer term persistance called SessionState or Cookies that will store values for a particular Session.
Here is a link from MSDN that contains interesting information regarding all the possible ways of saving state in an ASP.NET application. Let me know if you've got any other questions.
http://msdn.microsoft.com/en-us/library/75x4ha6s.aspx
--EDIT--
Here's a link to the MSDN article on Session State. My recommendation is to be careful with Session state and only store things that are absolutely required. Also I'd recommend you have a Class that contains the a bunch of constant for the Session Keys. It's easier to manage
http://msdn.microsoft.com/en-us/library/ms178581.aspx
ie instead of
string value = Session["Key"];
//Create a class SessionKeys
Class SessionKeys{
public const string SESSION_KEY = "Key"
}
//Now that string is strongly typed and you don't have to worry about misspelling it
string value = Sesssion[SessionKeys.SESSION_KEY];
The background to this question is that I need to use some user session data in a (static) WebMethod. I have created a static property that references the data I need like so:
private static UserWebSession UserWebSession
{
get
{
return (UserWebSession)HttpContext.Current.Session["UserWebSession"];
}
}
I can then call this in my page's static WebMethod.
My question is, is this technique thread safe? Or will this property's value be updated with every new page request - in other words, it will return the UserWebSession for the user who most recently requested the page?
That's fine - HttpContext.Current is designed precisely for this sort of thing. You won't get a previous user's session.
It's dependent on the thread though (I believe) - so if you start any extra background threads, they won't be able to see the current context.
Also be aware that although this call is safe in terms of not getting the wrong context, the normal concurrency caveats apply when it comes to what you actually do with the context.
I don't know that a Page Method is able to access Session state. If it can, then you may be ok. I recall that access to Session state is serialized, so that only one request at a time can arrive for a given session.
I need to retrieve a record from a database, display it on a web page (I'm using ASP.NET) but store the ID (primary key) from that record somewhere so I can go back to the database later with that ID (perhaps to do an update).
I know there are probably a few ways to do this, such as storing the ID in ViewState or a hidden field, but what is the best method and what are the reasons I might choose this method over any others?
It depends.
Do you care if anyone sees the record id? If you do then both hidden fields and viewstate are not suitable; you need to store it in session state, or encrypt viewstate.
Do you care if someone submits the form with a bogus id? If you do then you can't use a hidden field (and you need to look at CSRF protection as a bonus)
Do you want it unchangable but don't care about it being open to viewing (with some work)? Use viewstate and set enableViewStateMac="true" on your page (or globally)
Want it hidden and protected but can't use session state? Encrypt your viewstate by setting the following web.config entries
<pages enableViewState="true" enableViewStateMac="true" />
<machineKey ... validation="3DES" />
Do you want the end user to know the ID? For example if the id value is a standard 1,1 seed from the database I could look at the number and see how many customers you have. If you encrypt the value (as the viewstate can) I would find it much harder to decypher the key (but not impossible).
The alternative is to store it in the session, this will put a (very small if its just an integer) performance hit on your application but mean that I as a user never see that primary key. It also exposes the object to other parts of your application, that you may or may not want it to be exposed to (session objects remain until cleared, a set time (like 5 mins) passes or the browser window is closed - whichever happens sooner.
View state values cause extra load on the client after every post back, because the viewstate not only saves objects for the page, but remembers objects if you use the back button. That means after every post back it viewstate gets slightly bigger and harder to use. They will only exist on he page until the browser goes to another page.
Whenever I store an ID in the page like this, I always create a property
public int CustomerID {
get { return ViewState("CustomerID"); }
set { ViewState("CustomerID") = value; }
}
or
Public Property CustomerID() As Integer
Get
Return ViewState("CustomerID")
End Get
Set(ByVal value As Integer)
ViewState("CustomerID") = value
End Set
End Property
That way if you decide to change it from Viewstate to a session variable or a hidden form field, it's just a case of changing it in the property reference, the rest of the page can access the variable using "Page.CustomerID".
ViewState is an option. It is only valid for the page that you are on. It does not carry across requests to other resources like the Session object.
Hidden fields work too, but you are leaking and little bit of information about your application to anyone smart enough to view the source of your page.
You could also store your entire record in ViewState and maybe avoid another round trip to th server.
I personally am very leery about putting anything in the session. Too many times our worker processes have cycled and we lost our session state.
As you described your problem, I would put it in a hidden field or in the viewstate of the page.
Also, when determining where to put data like this, always look at the scope of the data. Is it scoped to a single page, or to the entire session? If the answer is 'session' for us, we put it in a cookie. (Disclaimer: We write intranet apps where we know cookies are enabled.)
If its a simple id will choose to pass it in querystring, that way you do not need to do postbacks and page is more accessible for users and search engines.
Session["MyId"]=myval;
It would be a little safer and essentially offers the same mechanics as putting it in the viewstate
I tend to stick things like that in hidden fields just do a little
<asp:label runat=server id=lblThingID visible=false />