Manually create/populate .NET Session object - c#

First a brief background. I am using .NET output caching and substitution controls to keep a few bits updated on each page refresh. The static methods that the substitution controls use require access to the Session object. Unfortunately, the HttpContext session is null in those methods.
I'm not going to rewrite my app to use a different store than the Session. Session is perfect for everything I need except this one aspect.
Can I manually create or populate a session object or otherwise get at its data by some sort of black magic wizardry? The session cookie is still being set from the client to the server. The info has got to be there somewhere. How do I get at it?

I'm not convinced this is a "good" way to go...but you can very dodgily store a reference to the Session in a shared/static variable and access it then.
Public Class SessionHelper
Public Shared TheSession As HttpSessionState
End Class
In your Session Start event (haven't figured out the best place to put it yet as the session isn't available in Application start as far as I am aware)
Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
' Store a reference...only do this once etc etc
If SessionHelper.TheSession Is Nothing Then
SessionHelper.TheSession = HttpContext.Current.Session
End If
End Sub
Then in your code you can just reference the helper
Dim someVariable as String = SessionHelper.TheSession.Item("ItemName")
A few things I'm not sure about this method:
not sure if the session object is now not thread safe
it doesn't seem quite right
this example is extremely simple...
Edit
I verified this worked for me by adding something to the cache and seeing if the session was available in the Cache Remove Callback which Http.Context.Current is not available in.
Edit 2
Here's a screenshot of it correctly returning the value. So it must be working to some degree, but the fact that the SessionId is not set is kind of worrying...I know I've used this technique before to access the Cache object but the cache is the cache, where as the session does need something to identify each session...Here you go anyway:

Session information is stored in the server's memory. You can, however, configure ASP.NET to store the session information inside SQL Server.

HttpContext.Current.Session should give you access to the current Session. The only time when this would not work is when there is no current HttpContext. As long as you have a reference to System.Web, it should work.

Related

Are objects stored in viewstate serialized? If so, how can I find the size of each viewstate["key"]?

The viewstate of a c# asp.net app that I am working on stores a ton of stuff via ViewState["SomeKey"] not to mention behind the scene stuff for several grids etc... and it is bloated.
I'm tasked with getting the viewstate size down...
I have found that within the app, viewstate is used to store various objects used throughout the code and I would like to use something more appropriate that stays session side (like session["SomeKey"]) or simply repopulate the objects again serverside... anyway...
I'd like to find where the largest benefit can be achieved by finding the heaviest objects that are stored in viewstate throughout the code... That is assuming they are serialized which I guess they must be... rather than holding a reference and hoping the object is in memory when posted back???
I would like to do something like the following...
var vsSomeKey = ViewState["SomeObjectKey"];
vsSomeKey.length.....
... with the hope of finding how much space is being used in viewstate for this key at this point in time... Any ideas?

Static Dictionary<T,T> sharing information accross sessions. How to stop this?

In my web project, I am using Static List. So say suppose I have 2 users (A, B) logged in to my website at the same time, then this List will store some information about A and as well as B. But say when I process B List's records, A's List's are getting processed instead of B's.
Can somebody point out the problem please?, also please suggest me some possible solution to avoid this problem.
I am using ASP.NET C# 3.5.
Thank you in advance :)
Edit:
Now I have changed the data type from Dictionary to List, but still the same problem...
A static variable is one that is the same for all instances of a particular class. So this means your website uses the exact same dictionary for User A, B, C, D, etc. Essentially whichever user last writes to the dictionary is the one whose content you will see, regardless of which user is looking.
As other's have suggested, you can use Session variables. These are stored in the server's memory, and are related to a specific browser 'session' (i.e. user).
Personally, I prefer to use the ViewState as this is stored in the response to the browser, and returned to you whenever the page makes a postback. This means less memory usage on the server, the viewstate is not volatile across sessions (or subject to application resets like session). However this also means that whatever you are storing is sent across the wire, so you would never want to store things like credit card numbers, SSN's, etc.
It also means that if you're storing a lot of very large objects, you're going to have a very large response and postback (possibly slowing the cycle), so you have to be more careful about how and what you store.
So that's a few different options for you, you should do the research and decide which is best for your requirements.
Storing values in session is like:
Session["mykey"] = value;
And reading values from session is like:
Object value = Session["mykey"];
The session will time out after a couple of minutes and the value would then be null.
To avoid this consider using:
Viewstate["mykey"] = value;
Viewstate is used exactly like session except that the value has to be serializable.
The viewstate is send to the client and back again so consider the amount of data that you want to store this way. The viewstate is stored in "__VIEWSTATE" and encoded in base64.
Don't use a static dictionary. Use Session variables to store information about a user's session.
For better information, you will have to provide us with a bit more information: what records? in what format? etc.
When a variable is declared static, that means there is exactly 1 instance of that variable per class (this also includes classes in web applications).
Thus, a static variable is not tied to a user. If you need to store data specific to a user, consider using a Session variable.
You could store the dictionary in the Session, that way each user would have their own and the code wouldn't have access to others.
Or if you sometimes want to be able to access other users' info, you could declare it as
static Dictionary<String, Dictionary<T, T>>
where the string key is the unique user id.

Maintain the SessionID for Entire Application in ASP.NET

I am implementing the Ecommerce projects, where I need to static SessionID, is there any way to maintain the SessionID in the Entire Application.Explanation of my question is here
session.sessionid in asp.net?
but How can I implement this approach.
Now I understand your point
you have to do something like this on the Global.asax file
protected void Session_Start(Object sender, EventArgs e)
{
Session["DummyData"] = "dummy";
}
Adding any value to the Session object at the very first moment after created, you avoids to get different SessionIDs because the Session object wasn't accessed yet.
EDIT
Anyway checking your last comment I don't see that this is something that is affecting your development in some way. Probably you're over thinking on this. If you just need to avoid users to buy more than X products, you don't care about this problem. When the first product is added to the session, the same SessionID will be used in successive requests, until it expires.
Reading the other post you mention, it sounds like either Session was not being used, and so a new Session ID was generated on each request. To fix this, just store something (anything) in the session on the first request to make sure it sticks.
Session["something"] = "anything";
Or, it could be that the user did not allow cookies, which would also cause a new session on each request. So, your users need to allow cookies.
Or you could use cookie-less session.
The other post explains it pretty well, I think.

Is there any way to know that user leaving a page with asp.net?

My question is a little bit tricky. at least I think. Maybe not, anyway. I want to know if there's any way to know if the user is leaving the page. Whatever if he clicks "Previous button", closing the window or ckicking on a link on my website. If my memory's still good, I think it's possible with JavaScript.
But in my case, I want to do some stuff (cleaning objects) in my codebehind.
There really is no way to do it. No event is fired when the browser goes back.
You can do it with Javascript, but it is difficult at best.
See the question here.
This script will also work. It was found here
<script>
window.onbeforeunload = function (evt) {
var message = ‘Are you sure you want to leave?’;
if (typeof evt == ‘undefined’) {
evt = window.event;
}
if (evt) {
evt.returnValue = message;
}
return message;
}
</script>
You can use javascript to tell the server when the user leaves the page. But the webserver washes it's hands of the page once it leaves the server, while the user might keep the page open for a week.
If you use javascript on the page to fire off a notice to your server when the page unloads you can take some action. But, you can't tell if he's leaving your page for another one of your pages, another website, or closing the browser.
And that last notice isn't guaranteed to always be sent, so you can't rely on it completely.
So using the javascript notice to clean up objects (caches or sessions) is a flawed system. You're better with cache & session invalidation strategies that are independent of the onunload notice.
If the goal of this is to cleanup objects in your code-behind, is it good enough to rely on the session timeout? It would be a 20 minute delay before cleaning up those objects (or whatever you have your session timeout set for).
But it's an easy and dependable way to do it. In your Global.asax file you'd just do this:
Sub Session_End(ByVal sender As Object, ByVal e As EventArgs)
' Clean up stuff
End Sub
As mentioned, you can do it unreliably in JavaScript, but I am assuming from the wording of your question that you want to do it in the Server-side code ("the code-behind").
That is impossible since the code-behind is running on a different computer (the web server) and has no idea what is going on at the user's computer unless the browser sends a request back to the server (which requires some Javascript or other client side code).
If you must, use the session timeout events to clean up any state information you are storing beyond the lifetime of a request.
Euuwww ... well ok. My problem it's because I've stored in a Session variable an objects (with a bunch of search criterias). By storing it in a session variable, if the user go back to my search page result, it will list back the same result as last time. But, after some reflexion (not in code but in my head and after seen your answer :oP), I will add a boolean property in my object which will mean something like "IsDirty" or "HasBeenListed". And when i will load back, if its set to dirty, it's gonna redirect back to another page.
Thank David.

Beginner how do you maintain state in an ASP C# Web Page

Update: the clearest explanation I have found on the web as I have been struggling through this can be found here.
Maybe I just don't understand the model of runat server terribly well. It appears the following code is always executing the if block. If the code is running on the server side I guess I can understand that it has to be stateless.
I am a seasoned non-web programmer but it appears counter intuitive to me. Will I need to create some sort of session object or pass the current state along in the URL or what?
<script runat="server">
DateTime begin;
DateTime end;
int iSelectedStart = 0;
int iSelectedEnd = 0;
int iPutName = 0;
protected void Button1_Click(object sender, EventArgs e)
{
if (iPutName == 0)
{
iPutName = 1;
Label1.Text = TextBox1.Text + " you will be slecting your start and end dates.";
It looks like part of your code got cut off, but here's the basic thing with web programming -- it's stateless. Unless, that is, you do something (use ViewState, Session, etc.) to add some state into the mix.
In your case, it looks like you want to maintain some state through refreshes of the page. Put the values you want to preserve in ViewState to keep them across postbacks to the same page. If you want to hold values across pages on your site, use Session. If you want to maintain values across visits to the site, put them in a database and tie them to a login or cookie.
The important thing to remember here is that the web is stateless. Each request from a person's browser is completely separate from all previous requests. What's happening with your code is that the class is being instantiated from scratch each time the client requests a page. That includes clicking Button1.
If you want values to persist between requests, you have to store it in a location where it can be retrieved later. The Session object provides this for you.
Basically, you'll need to store the iPutName variable in the session somehow. Probably the nicest way is to encapsulate it in a property:
protected int iPutName
{
get {
if (Session["iPutName"] == null)
Session["iPutName"] == 0;
return Session["iPutName"];
}
set { Session["iPutName"] = value; }
}
Edit: The ViewState object will work as well (as long as ViewState is turned on on the page). This encodes the value in a hidden field in the HTML and decodes it when it comes back.
Edit (again): Apologies for repeated edits, but I should clear this up. What Jonathan and Emil have said is correct. You should probably be using ViewState for this rather than Session unless you want this value to remain accessible between pages. Note that this does require that ViewState is turned on and it will result in a larger payload being sent to the client.
I really recommend to look at the quick start tutorial.
http://quickstarts.asp.net/QuickStartv20/aspnet/Default.aspx
There are a lot of concepts in dot net to simulate state on the UI.
In your case I think what you really want to do is using viewstate. Sessions should be used with care and I think the concept you are looking for i localized to the page not to the entier user session.
You should also look at the concept codebehind/codefront as well.
Because ASP.NET is stateless what you're assuming is correct. The postback will cause the page to lose the variable for iPutName. Storing in session is one option, or storing in viewstate could be another option.
The main thing to understand here is how the ASP.NET page lifecycle works and what happens each time you post back to the server.
For the lifecycle, check out the following URL :
http://www.eggheadcafe.com/articles/20051227.asp
You can store your iPutName in the session by doing this :
Session["iPutName"] = iPutName;
Fetching the session variable is also easy, but you should be sure to do a NULL check, like this:
if (Session["iPutName"] != null) iPutName = Session["iPutName"];
Haven't tested any of this, but if you encounter typos... sorry ;)
The Url you posted in your update is definitely not "All You Want to Know" about ViewState.... not even close. I only scanned his article but he doesn't appear to address Page Life Cycle at all. If your going the View State route then read these 2 links:
Understanding ASP.NET View State by Scott Mitchell
Truly Understanding ViewState By Dave Reed
If you're new to ViewState then dump all that guff (1 half the article) about parsing ViewState mentioned in your linked article. It's simply not required for anything but highly specialized scenarios. It is definitely not a normal thing to be doing re:ViewState.

Categories