how can I get IDs of all current sessions?
To get the session id, do this:
// In a user control or page
string sessionId = this.Session.SessionID;
// In a normal class, running in a asp.net app.
string sessionId = System.Web.HttpContext.Current.Session.SessionID;
You should not need to:
Make any data table or loop anything
Use SQL server for session state
Handle Session_Start or Session_End
In a cookieless scenario, the session id is created when you access the Session object for the first time. This shouldn't matter much, because the moment you access the SessionID property, the session object is accessed.
For more info, look into this:
http://msdn.microsoft.com/en-us/library/system.web.sessionstate.httpsessionstate.sessionid.aspx
Note: The msdn examples have been written by monkeys.
You can use Global.asax file and set the Session at Session_Start event. See below
in Global.asax file you can do something like this:
protected void Session_Start(object sender, EventArgs e)
{
Session["sid"] = Session.SessionID;
Session["sid"] = "Test";
}
Then in your WebForm you can get the Session ID and Value like below
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("Session ID is:" + Session.SessionID.ToString()+ "<br/>");
Response.Write("Session value is:" + Session["sid"].ToString());
}
For details, see http://www.dotnetcurry.com/ShowArticle.aspx?ID=126
According to Dino Esposito each session is stored in the application's Cache and with some work you can retreive this information:
DataTable dt = new DataTable();
dt.Columns.Add("SessionID", typeof(string));
foreach(DictionaryEntry elem in Cache) {
string s = elem.Key.ToString();
if (s.StartsWith("System.Web.SessionState.SessionStateItem")) {
DataRow row = dt.NewRow();
char[] parms = {':'};
string[] a = s.Split(parms);
row["SessionID"] = a[1];
dt.Rows.Add(row);
}
}
If you want a way to store a list of the current sessions where you control the backing store, so that you may store extra data about the client, you can use a list. (I'm writing the following example from the top of my head)
Hook into Application_SessionStart in the global.asax.cs file:
static List<string> sessions = new List<string>();
static object sessionLock = new object();
void Application_SessionStart()
{
lock (sessionLock) {
sessions.Add(Session.SessionID);
}
}
void Application_SessionEnd()
{
lock (sessionLock) {
sessions.Remove(Session.SessionID);
}
}
Alternatively, you can use a dictionary, storing the session ID as a key, and extra data about that user as the value. Then you can easily create a page that shows all current user sessions, for example, for an admin site to show current user sessions.
SessionEnd will only be called if your sessions are InProc.
The answer depends partially on where you store session state. Assuming you use the default (inproc) then you can maintain a list of current session ids using the Session_Start and Session_End events in global.asax.
If you are storing your session state in SQL Server, you can also easily get it from there.
Related
I have a scenario where i have a page which opens a dialog on click of a button, in the opened dialog form on button click i can read a list of data from a selected .txt file and build a query and add the data to some database tables. Since there could be large amount of data this process can take large time because of this the user would not be able to work on the application until the upload completes. Hence to make the upload process Asynk i am using the PageAsyncTask. Below is the code sample, but in the method called in the PageAsyncTask the HttpContext.Current is null hence i am not able to use session handling. Please any guidance on this why would this be null and how can i use the session in this case
protected void BtnUpload_click(object sender, EventArgs e)
{
PageAsyncTask asyncTask1 = new PageAsyncTask(OnBegin, OnEnd, OnTimeout, SessionManager.UserData, true);
Page.RegisterAsyncTask(asyncTask1);
Page.ExecuteRegisteredAsyncTasks();
}
public IAsyncResult OnBegin(object sender, EventArgs e,
AsyncCallback cb, object extraData)
{
_taskprogress = "AsyncTask started at: " + DateTime.Now + ". ";
uData = extraData as UserData;
_dlgt = new AsyncTaskDelegate(BeginInvokeUpload);
IAsyncResult result = _dlgt.BeginInvoke(cb, extraData);
return result;
}
private void BeginInvokeUpload()
{
string selectedFileName = string.Empty;
string returnValuePage = string.Empty;
User teller = new User();
SessionManager.UserData = uData;
}
private void BeginInvokeUpload()
{
string selectedFileName = string.Empty;
string returnValuePage = string.Empty;
User teller = new User();
SessionManager.UserData = uData;
}
public class SessionManager
{
public static UserData UserData
{
get
{
UserData userData = null;
if (HttpContext.Current.Session["UserData"] != null)
{
userData = HttpContext.Current.Session["UserData"] as UserData;
}
return userData;
}
set
{
HttpContext.Current.Session["UserData"]=value;
}
}
}
The answer is simple : you can not use the session if the HttpContext.Current is null
So if you need to modify the session you simple can not and the only alternative is to make your totally custom session module/solution.
If you only need to read some values, then you can pass them when you create your thread.
And finally the only solution is to not use the thread if you won to manipulate the session variables.
why this design?
why MS session did not allow you to handle it out side of a page and inside a thread ? the answer is because is need to lock the session data on page processing - with this lock even if you start a thread and been able to get the session data, will not been able to use it parallel.
Also if you been able to use the session your self in a thread, then this thread may lock the entire page view process, because I say it again, session is lock the entire page view, and each page that use the same session are not work in parallel
This lock of session on the entire page is necessary the way the MS session works, and the only way to avoid that is to make a totally custom session solution, and handle special cases with different code.
The good about that design is that you avoid to make a lot of locking and synchronization by your self on every page call - for example if you disable the session on a page, and use that page for data inserting, if a use make multiple double clicks on the insert, and you do not handle it with synchronization on the insert, you end up with multiple same insertions.
More about session lock:
Replacing ASP.Net's session entirely
Web app blocked while processing another web app on sharing same session
jQuery Ajax calls to web service seem to be synchronous
ASP.NET Server does not process pages asynchronously
Similar question:
How to get Session Data with out having HttpContext.Current, by SessionID
I'm using VS2010 and created a simple asp. web forms application, using Development Server to test it.
I try to store user data - queried from sql server - in the session, since I don't want to access database in every request. I'm using the 'Application_AuthenticateRequest' and the 'Session_Start' methods.
First round:
AuthenticateRequest called. The following code ran:
public static void Initialize(string login_name, bool force_refresh)
{
HttpSessionState Session = HttpContext.Current.Session;
object o = Session == null ? null : Session["EMPLOYEE_DATA"];
if (force_refresh || o == null || o.GetType() != typeof(Employee) || (o as Employee).login_name!= login_name)
{
_current = UIManager.GetEmployee(login_name);
if (Session != null)
{
Session["EMPLOYEE_DATA"] = _current;
}
}
else
{
_current = (Employee)o;
}
}
The _current variable is a private static field published through a static property.
In the first round the Session is null, and I think it's ok because the Session_Start not called yet.
The Session_Start looks like this:
protected void Session_Start(object sender, EventArgs e)
{
Session["EMPLOYEE_DATA"] = EmployeeFactory.Current;
}
In the next round the Session_Start is not called of course but in the AuthenticateRequest I can't access to the session. The HttpContext.Current.Session is null and the this.Session reference throw a HttpException says the "Session state is not available in this context".
However I can access the Session from any of the page_load events but it's a bad practice I think that I put authentication every page_load.
Any idea how can I access to the Session?
Thanks for advice,
Péter
You're not able to use Session on the Application_AuthenticateRequest becauase it's not bound at that moment.
I think you're able to use the event Application_AcquireRequestState.
try to use the below code in page_Load
Response.AppendHeader("Refresh", Convert.ToString(Session.Timeout * 15) + ";
URL=SessionExpPage.aspx");
I know this probably isn't possible, but I would like to be able to get the Request user ID from within an ASP.NET web service method. So far, I've tried User.Identity.Name, Context.Request.LogonUserIdentity.Name, Request.ServerVariables["AUTH_USER"] and Request.ServerVariables["LOGON_USER"]. Am I tilting at windmills here, or is there something super simple that I'm missing?
Well, what do you mean by User ID?
If they've authenticated via Windows Authentication, User.Identity gives you the WindowsIdentity object that corresponds to that user.
If you want the User ID which corresponds to an authenticated user to "magically" show up in your pages, you can do that too! In your Global.asax, there is a function called Application_AuthenticateRequest which you implement to take whatever identity is passed to your application and turn it into a IPrincipal-based object which can be accessed from your pages.
So when you implement AuthenticateRequest(), you can take the HttpContext.Current.User.Identity.Name, and use that to look up your User ID from your database. From there, you construct your own IPrincipal-derived object and set the HttpContext.Currrent.User reference to that object you create. You can then cast "User" in your pages over to the object you create and read the User ID. We do this all the time. Here's some sample code (which actually caches the Principal object so that you don't have to go to the DB on every request):
protected void Application_AuthenticateRequest(object sender, EventArgs e) {
try {
IIdentity myIdentity = HttpContext.Current.User.Identity;
MyPrincipal myPrincipal = (MyPrincipal)HttpContext.Current.Cache[myIdentity.Name];
if (myPrincipal == null) {
myPrincipal = (MyPrincipal)GetPrincipalFromDatabase(HttpContext.Current.User.Identity);
HttpContext.Current.Cache.Insert(myIdentity.Name, myPrincipal, null, DateTime.Now.AddMinutes(1), TimeSpan.Zero);
}
HttpContext.Current.User = myPrincipal;
}
catch (SecurityException) {
HttpContext.Current.User = null;
}
catch (Exception ex) {
Trace.WriteLine("Could not validate your user.");
}
}
I'm recording the session start times from when people log into my .NET 2.0 web application, but I'd also like to record the Session ID. Can someone give me some example code on how to accomplish this (how to access the Session ID from within the Global.ASAX).
If you need any additional info just let me know.
HttpContext.Current.Session.SessionID
Edit to show null test:
if ((HttpContext.Current != null) && (HttpContext.Current.Session != null) {
id = HttpContext.Current.Session.SessionID
}
You can get at it quite simply with HttpContext.Current.Session.SessionId as you probably already know. You need to be on or after Application_AcquireRequestState before the session state has been loaded, and session state is also only loaded when the requested resource implements IRequiresSessionState. You can see a list of all the events in global.asax here: https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-5771721.html and read more about IRequiresSessionState here: http://msdn.microsoft.com/en-us/library/system.web.sessionstate.irequiressessionstate.aspx
Write to the session the datetime and sessionid at the moment of the first request following ASP.NET's identifying the user's session.
protected void Application_PreRequestHandlerExecute(object sender, EventArgs eventArgs) {
var session = HttpContext.Current.Session;
if (session != null) {
if (session["foo"] == null) {
session["foo"] = DateTime.Now.Ticks + "|" + session.SessionID;
}
}
}
Can anybody help me to find out solution of following problem.
In ASP.NET website: at Application_OnPostAuthenticate() event, whatever code i write is executed for every request. therefore due to this customidentity object, countryid and weatherid is called everytime for each request (call for database for value). It effect response time of page and unneccessary code execute.
void Application_OnPostAuthenticateRequest(object sender, EventArgs e)
{
// Get a reference to the current User
IPrincipal objIPrincipal = HttpContext.Current.User;
// If we are dealing with an authenticated forms authentication request
if ((objIPrincipal.Identity.IsAuthenticated) && (objIPrincipal.Identity.AuthenticationType == "Forms"))
{
CustomPrincipal objCustomPrincipal = new CustomPrincipal();
objCustomPrincipal = objCustomPrincipal.GetCustomPrincipalObject(objIPrincipal.Identity.Name);
HttpContext.Current.User = objCustomPrincipal;
CustomIdentity ci = (CustomIdentity)objCustomPrincipal.Identity;
HttpContext.Current.Cache["CountryID"] = FatchMasterInfo.GetCountryID(ci.CultureId);
HttpContext.Current.Cache["WeatherLocationID"] = FatchMasterInfo.GetWeatherLocationId(ci.UserId);
Thread.CurrentPrincipal = objCustomPrincipal;
}
}
To solve this problem when i try tochange code as follows
HttpContext.Current.Session.Add("test", FatchMasterInfo.GetWeatherLocationId(ci.UserId);); in place of cache i found foolowing error
"Object refrence not set to the instance of object"
I don't know whether we can store session variable inside Application_OnPostAuthenticate() event or not?
You could try doing this a bit later in the request, such as in the PreRequestHandlerExecute event:
protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
IPrincipal objIPrincipal = HttpContext.Current.User;
if ((objIPrincipal.Identity.IsAuthenticated) && (objIPrincipal.Identity.AuthenticationType == "Forms"))
{
HttpSessionState session = HttpContext.Current.Session;
CustomPrincipal objCustomPrincipal = new CustomPrincipal();
if (session[objIPrincipal.Identity.Name] == null)
{
// get data from database or wherever
objCustomPrincipal = objCustomPrincipal.GetCustomPrincipalObject(objIPrincipal.Identity.Name);
CustomIdentity ci = (CustomIdentity)objCustomPrincipal.Identity;
Object countryID = FatchMasterInfo.GetCountryID(ci.CultureId);
Object weatherLocationID = FatchMasterInfo.GetWeatherLocationId(ci.UserId);
// save in session (not cache as cache is application-wide, not per-user):
session.Add(objIPrincipal.Identity.Name, objCustomPrincipal);
session.Add(objIPrincipal.Identity.Name + "_CountryID", countryID);
session.Add(objIPrincipal.Identity.Name + "_WeatherLocationID", weatherLocationID);
}
else
{
// already have custom principal object in session
objCustomPrincipal = (CustomPrincipal)session[objIPrincipal.Identity.Name];
}
// set the custom principal object to context/thread
HttpContext.Current.User = objCustomPrincipal;
Thread.CurrentPrincipal = objCustomPrincipal;
}
}
You probably don't want to access the session in any event that happens in every request. Some requests don't even have session (for instance, a lot of web service calls, or calls to WebResource.axd that load static resources).
Before adding value to cache object, check if it already exists in the cache.
You might not have session state enabled. Does it work anywhere else (like in a web form's display)?
Look for a <sessionState> element under your system.web element in web.config make sure it's turned on (set it to InProc unless you have a web farm).