Can ASP.NET session remember objects? - asp.net

I start my question from an example. I think it will be more simple.
What i want to do, is send REQUEST_1 from my Android device to asp page, which is waiting for JSON request, for example {"Year":2012}. Page takes this json string, and saves it to the object (example arraylist).
After a minute, I send REQUEST_2 to the same ASP page with data: {"Command","WhatIsCurrentYear"}, and I then want to get response: {"Year",2012} (which should still be stored in the arraylist).
Is there a chance to do this?

Session has a property Session.TimeOut. Session expires after the time expires. By default in asp.net session Timeout time is 20 mintues Also if user closes the browser session also expires if it's mode is InProc ( Cookies or without cookies ). In InProc session provider IIS could recycle the application pool at any moment (period of inactivity, certain CPU/memory thresholds are reached, ...) without warning voiding the contents of this session.
Variables are initialized on every post back, so if previously you had saved data in an array list object it is lost. To save data during postbacks you can use ViewState.

I created a class for accessing the session
public static IPerson User
{
get
{
if (HttpContext.Current.Session == null || HttpContext.Current.Session[UserConstant] == null)
return new Student();
return (IPerson)HttpContext.Current.Session[UserConstant];
}
set
{
HttpContext.Current.Session[UserConstant] = value;
}
}
You can replace IPerson with whatever object you want.

Related

How to create a timer for counting reservation time in asp.net?

I've created a hotel room reservation website. Assume that a person who wants to reserve a room has 30 mins time to do that and after 30 mins the site would stop the reservation session for him; during this reservation he would pass several web page for filling the information.
Is there any way to create a timer which can calculate 30 mins during SEVERAL PAGES?
A timer would always get re-initialized when the user would reload the page after submitting the page unless you are having a Single page application.
Another simple way would be to store a cookie with the date time value when the user started filling in the forms (or what so ever is the initial stage). You can create it this way,
// Set the cookie
HttpCookie cookie = new HttpCookie("date");
// Add the value
cookie["dateValue"] = DateTime.Now.ToString();
// Add the cookie
Response.Cookies.Add(cookie);
Then you can check this cookie and (after successful casting to DateTime object) you can check whether user has some time in his 30 minutes trial period or whether he is late. You can get the cookie on the server-side using this code,
// This check would minimize one error
if(Request.Cookies["data"]["dateValue"] != null) {
var time = Convert.ToDateTime(Request.Cookies["data"]["dateValue"]);
} else {
// Maybe cookie got removed.
}
This way you can set this functionality in your ASP.NET web application.

Asp .net session variables update by thread is not getting reflected in Session

In my page1.aspx i am generating a report from database by using thread.
//on button click
Hashtable ht = (Hashtable)Session["ReportParam"];
ReportThreadClass rth = new ReportThreadClass(ht);
Thread thread = new System.Threading.ThreadStart(rth .Run);
thread.Start();
In my thread class's rum method i am updating values in Hashtable that how many pages i have created.
//in thread' method
public virtual void Run()
{
int pagecount=0;
while(done)
{
//loading data from DB and generating html pages
ht["Total_Pages"] = pagecount;
}
}
At my Page2.aspx i am reading values from Session Variable
Hashtable ht = (Hashtable)Session["ReportParam"];
int TotalPages = (int) ht["Total_Pages"];
When i run above code in InProc mode every thing is working fine i am getting updated values from session.
Because every thing is stored in static variable, and ht is referenced by Session so it automatically get updated in session (HashTable not needed to reassign it to session back).
But when i run code in State server (OutProc mode) It need to store session data in different process by Serializing Hash-table.
But the value of Total_Pages is not getting updated in Page2.aspx even after Thread run completely.
So is there any event or method which get fired to store all updates in session variable to State-Server , if yes then pls tell me . if not then pls suggest me some idea to get updated value in page2.aspx.
I would explictely SET and GET SessionState like so:
In your thread Run
// no complex object like hastable, just a plain value...
Session["pageCount"] = pageCount;
In your page2.apsx:
var pageCount = (int) Session["pageCount"]??0;
The reason your report thread is not updating it's session value when using out-of-proc sessionstate is because the session has no way to detect the hashtable has a changed value, therefor it doesn't update the underlying storew with the serialized version of the hastable. When you explicity store one immutable object it will persist one it's value changed;
As the session might already be gone when your thread finishes a begtter option is to get hold of a reference to SqlSessionStateStore and call SetAndReleaseItemExclusive. Ultimately you might want to have an overloaded SessionStateProvider that can handle your scenario.
In Out Proc Mode Session is saved after some event so if your thread is updating your session variables then it won't persist in storage.
If u are using Inproc Mode then session store in Static Dictionary so if your thread updating it, u will get updated value to any page.
So u have two solutions for this situation
Use inProc mode
Maintain a dictionary in your thread class with key as Session id and value is your hash-table, So if page2.aspx wants to read value of hash-table then it will pass his session id to method and which will return required value.
Less efficient but I'd probably just ping the database for the page count on Page2.
Or create a separate session value for the page count on Page1, at the same time as doing everything else. (EDIT: Nevermind the second part, that's what Rene suggested below).

NHibernate holding on to a reference to data objects

I'm trying to work out where a lot of the memory in my app is going and while doing some profiling I'm noticing that any data objects that are loaded by NHibernate are hanging around once the request (is asp.net), and therefore session, has ended. Tracing it back, there are various things that seem to be doing it, like the "SingleTableEntityPersister" and the "StatefulPersistenceContext". I've disabled 2nd level caching for now, but they're still being held on to
Any ideas?
The session is being correctly disposed:
if (session != null)
{
if (session.Transaction != null && session.Transaction.IsActive)
{
session.Transaction.Rollback();
}
else
{
session.Flush();
}
session.Close();
session.Dispose();
}
NHibernate tracks all changes that are made to objects, that means that if you do:
user.FirstName = "name"
it will make the appropriate update in the DB.
But to track this NH needs references to all your objects. To get not tracked entities you can either use IStatelessSession or remove object from the session using the Evict method.
When session is disposed it releases all the tracked entities. So check if session is deleted properly and transaction is closed

ASP.NET session object lifetime pessimistic assumption !

I check a session object and if it does exist then call another method which would use that object indirectly. Although the second method would access this object in a few nanoseconds I was thinking of a situation when the object exactly expires between two calls. Does Session object extends its lifetime on every read access from code for preventing such a problem ? If not how to solve the problem ?
If you are going to say why I don't pass the retrieved object from first method to second one, this is because I pass the ASP.NET Page object which carries many other parameters inside it to second method and if I try to pass each of them separately, there would be many parameters while I just pass one Page object now.
Don't worry, this won't happen
If I understand your situation it works sort of this way:
Access a certain page
If session is active it immediately redirects to the second page or executes a certain method on the first page.
Second page/method uses session
You're afraid that session will expire between execution of the first and second method/page.
Basically this is impossible since your session timer was reset when just before the first page starts processing. So if the first page had active session then your second page/method will have it as well (as long as processing finishes before 20 minutes - default session timeout duration).
How is Session processed
Session is processed by means of an HTTP Module that runs on every request and before page starts processing. This explains the behaviour. If you're not familiar with HTTP Modules, then I suggest you read a bit about IHttpModule interface.
It's quite difficult to understand your question, IMHO, but I will try.
From what I understand, you're doing something like:
string helloWorld = string.Empty;
if (this.Session["myObject"] == null)
{
// The object was removed from the session or the session expired.
helloWorld = this.CreateNewMyObject();
}
else
{
// Session still exists.
helloWorld = this.Session["myObject"].ToString(); // <- What if the session expired just now?
}
or
// What if the session existed here...
if (this.Session["myObject"] == null)
{
this.Session["myObject"] = this.CreateNewMyObject();
}
// ... but expired just there?
string helloWorld = this.Session["myObject"].ToString();
I thought that Session object is managed by the same thread as the page request, which would mean that it is safe to check if object exists, than use it without a try/catch.
I were wrong:
For Cache objects you have to be aware of the fact that you’re dealing essentially with an object accessed across multiple threads
Source: ASP.NET Cache and Session State Storage
I were also wrong about not reading to carefully the answer by Robert Koritnik, which, in fact, clearly answers the question.
In fact, you are warned about the fact that an object might be removed during page request. But since Session lifespan relies on page requests, it would mean that you must take in account the removal of session variables only if your request takes longer than the session timeout (see How is Session processed in the answer by Robert Koritnik).
Of course, such situation is very rare. But if in your case, you are pretty sure that the page request can take longer than 20 minutes (default session timeout), than yes, you must take in account that an object may be removed after you've checked if it exists, but before you really use it.
In this situation, you can obviously increment the session timeout, or use try/catch when accessing the session objects. But IMHO, if the page request takes dozens of minutes, you must consider other alternatives, as Windows services, to do the work.
I'm having difficulties understanding what the problem here is but let me try it again referring to thread safety.
Thread safety issue
If this is a thread safety issue, you can always issue a lock when creating a certain session object so other parallel requests won't run into a problem by double creating your object.
if (obj == null)
{
lock (objLock)
{
if (obj == null)
{
obj = GenerateYourObject();
}
}
}
Check lock documentation on MSDN if you've never used it before. And don't forget to check other web resources as well.

ASP.NET cache objects read-write

what happens if an user trying to read HttpContext.Current.Cache[key] while the other one trying to remove object HttpContext.Current.Cache.Remove(key) at the same time?
Just think about hundreds of users reading from cache and trying to clean some cache objects at the same time. What happens and is it thread safe?
Is it possible to create database aware business objects in cache?
The built-in ASP.Net Cache object (http://msdn.microsoft.com/en-us/library/system.web.caching.cache.aspx) is thread-safe, so insert/remove actions in multi-threaded environments are inherently safe.
Your primary requirement for putting any object in cache is that is must be serializable. So yes, your db-aware business object can go in the cache.
If the code is unable to get the object, then nothing / null is returned.
Why would you bother to cache an object if you would have the chance of removing it so frequently? Its better to set an expiration time and reload the object if its no longer in the cache.
Can you explain "DB aware object"? Do you mean a sql cache dependency, or just an object that has information about a db connection?
EDIT:
Reponse to comment #3.
I think we are missing something here. Let me explain what I think you mean, and you can tell me if its right.
UserA checks for an object in cache
("resultA") and does not find it.
UserA runs a query. Results are
cached as "resultA" for 5 minutes.
UserB checks for an object in cache
("resultA") and does find it.
UserB uses the cached object "resultA"
If this is the case, then you dont need a Sql Cache dependency.
Well i have a code to populate cache:
string cacheKey = GetCacheKey(filter, sort);
if (HttpContext.Current.Cache[cacheKey] == null)
{
reader = base.ExecuteReader(SelectQuery);
HttpContext.Current.Cache[cacheKey] =
base.GetListByFilter(reader, filter, sort);
}
return HttpContext.Current.Cache[cacheKey] as List<CurrencyDepot>;
and when table updated cleanup code below executing:
private void CleanCache()
{
IDictionaryEnumerator enumerator =
HttpContext.Current.Cache.GetEnumerator();
while (enumerator.MoveNext())
{
if (enumerator.Key.ToString().Contains(_TableName))
{
try {
HttpContext.Current.Cache.Remove(enumerator.Key.ToString());
} catch (Exception) {}
}
}
}
Is this usage cause a trouble?

Resources