167

I have created a class file in the App_Code folder in my application. I have a session variable

Session["loginId"]

I want to access this session variables in my class, but when I am writing the following line then it gives error

Session["loginId"]

Can anyone tell me how to access session variables within a class which is created in app_code folder in ASP.NET 2.0 (C#)

M4N
  • 94,805
  • 45
  • 217
  • 260
djmzfKnm
  • 26,679
  • 70
  • 166
  • 227

7 Answers7

374

(Updated for completeness)
You can access session variables from any page or control using Session["loginId"] and from any class (e.g. from inside a class library), using System.Web.HttpContext.Current.Session["loginId"].

But please read on for my original answer...


I always use a wrapper class around the ASP.NET session to simplify access to session variables:

public class MySession
{
    // private constructor
    private MySession()
    {
      Property1 = "default value";
    }

    // Gets the current session.
    public static MySession Current
    {
      get
      {
        MySession session =
          (MySession)HttpContext.Current.Session["__MySession__"];
        if (session == null)
        {
          session = new MySession();
          HttpContext.Current.Session["__MySession__"] = session;
        }
        return session;
      }
    }

    // **** add your session properties here, e.g like this:
    public string Property1 { get; set; }
    public DateTime MyDate { get; set; }
    public int LoginId { get; set; }
}

This class stores one instance of itself in the ASP.NET session and allows you to access your session properties in a type-safe way from any class, e.g like this:

int loginId = MySession.Current.LoginId;

string property1 = MySession.Current.Property1;
MySession.Current.Property1 = newValue;

DateTime myDate = MySession.Current.MyDate;
MySession.Current.MyDate = DateTime.Now;

This approach has several advantages:

  • it saves you from a lot of type-casting
  • you don't have to use hard-coded session keys throughout your application (e.g. Session["loginId"]
  • you can document your session items by adding XML doc comments on the properties of MySession
  • you can initialize your session variables with default values (e.g. assuring they are not null)
M4N
  • 94,805
  • 45
  • 217
  • 260
  • Hi, we have to write code for get and set, right? "public int LoginId { get; set; }" – djmzfKnm Apr 07 '09 at 11:18
  • I have written it like: get { return Convert.ToString(HttpContext.Current.Session["webm_login"]); } set { HttpContext.Current.Session["webm_login"] = value; } – djmzfKnm Apr 07 '09 at 11:19
  • 6
    There's no need to write any code, use as shown in the answer. E.g. "public int LoginId { get; set; }" --> this is called an automatic property. – M4N Apr 07 '09 at 13:00
  • When I am using your method, property without any definition then its giving me "CS0501: 'ItsSession.webm_login.get' must declare a body because it is not marked abstract or extern" – djmzfKnm May 02 '09 at 10:39
  • Please tell me why its creating problem. – djmzfKnm May 02 '09 at 10:40
  • 4
    If you are using .net 3.x you can use automatic properties as shown in my code. With .net 2.x/1.x this is not available and you have to implement the getter/setter of your properties yourself: private int _loginId; public int LoginId { get { return _loginId; } set { _loginId = value; } } – M4N May 02 '09 at 15:56
  • Ok, so that means automatic properties are available in .net 3.x . I am using 2.x may be that's why automatic properties are not working. Thanks – djmzfKnm Jun 08 '09 at 04:52
  • 2
    Looks cool now, I think i got the answer of my problem, and I am alreday using your way, its very clean and easy to maintain all my session variables at one place. Thanks @Martin, you are AWESOME. – djmzfKnm Jun 08 '09 at 04:53
  • 23
    @M4N, Wish I could express a bit more gratitude than a +1. This has become my favorite way of dealing with the session/cache in my projects. My code, literally, is thanking you. – Brandon Boone Aug 28 '10 at 14:13
  • 1
    Now that is programming. One Gold Medal For you – irfandar Jan 18 '13 at 19:56
  • @M4N: Where would this class be preferably placed in the case of an ASP.NET Web Application? Thanks – Răzvan Flavius Panda Mar 05 '13 at 09:30
  • 2
    @M4N, wouldn't you mark the class as `[Serializable()]` in case it needs to be used in an out of proc session store? – David d C e Freitas Nov 04 '13 at 03:04
  • 1
    @M4N Could you explain public static MySession Current { get { MySession session = (MySession)HttpContext.Current.Session["__MySession__"]; if (session == null) { session = new MySession(); HttpContext.Current.Session["__MySession__"] = session; } return session; } } – irfandar Nov 30 '13 at 11:48
  • 1
    Is this valid for a multi-user web application? Even though it populates the class members with what is in session isn't the public class static? That means the class/members could be bounced back and forth when multiple users are accessing the application at the same time...right? What am I missing? – Kristopher Sep 21 '15 at 15:43
  • 4
    @Kristopher while the 'Current' property is static the instance of MySession returned is not...so it's fine. Static **methods and properties** are safe to use in this way. – Darren Nov 12 '15 at 22:52
  • 1
    It looks like with this construct, if you want to check one of the properties values, then you end up creating a session variable with \_\_MySession\_\_ as key. And if you are only checking for whether, say Session["loginId"] is null, then this code has to create the Current session first. Is there a way around it? – GMalla Sep 27 '16 at 23:06
  • 1
    this is brilliant but i wonder if anyone has considered or tried to quantify the implication of using this technique with a larger/more complex set of properties? Presumably every session will contain every property even if it is empty? Additionally, if you're not using inproc then the class will have to be serialised/de-serialised which could be expensive? – Lee Tickett Jul 20 '17 at 20:39
  • @M4N can you please help me, where i am wrong, it always return me null see my question: https://stackoverflow.com/questions/45254279/always-return-null-error-while-get-set-session-variable-in-any-c-sharp-asp-net thanks in advance – adnan Jul 26 '17 at 13:05
  • @M4N In this approach I have one doubt, i.e. whenever I need to access any property from the session, then each time entire MySession object will get de-serialized. I am using outproc session at redis and in mu case MySession class have complex nested type as property. So does it not make performance impact? Because each time I am reading and writing entire object even if I need the value of single key (Property), I am considering that as the object get heavy serialization and de-serialization operations will be costly. – Ashish Shukla Nov 22 '18 at 11:47
  • I cant set value for the properties dynamically. Please someone help me – Prem Jul 04 '19 at 02:52
113

Access the Session via the thread's HttpContext:-

HttpContext.Current.Session["loginId"]
Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
AnthonyWJones
  • 187,081
  • 35
  • 232
  • 306
  • Thanks a ton Anthony for this simple step. – Kings Mar 22 '12 at 15:04
  • Thanks a lot Anthony ,+1 for that – DayTimeCoder Jun 07 '12 at 15:12
  • Thanks. Forgot what the namespace was :) – Anthony Horne Nov 17 '14 at 07:18
  • @AnthonyWJones i used your method, but have problem, can you explain me, where i am wrong or what is proper way to use, my question https://stackoverflow.com/questions/45254279/always-return-null-error-while-get-set-session-variable-in-any-c-sharp-asp-net – adnan Jul 24 '17 at 05:23
  • and if you want to convert to HttpSessionStateBase: HttpSessionStateBase session = new HttpSessionStateWrapper(HttpContext.Current.Session); re: https://stackoverflow.com/questions/5447611/why-are-there-two-incompatible-session-state-types-in-asp-net – sobelito Oct 26 '19 at 06:17
24

The problem with the solution suggested is that it can break some performance features built into the SessionState if you are using an out-of-process session storage. (either "State Server Mode" or "SQL Server Mode"). In oop modes the session data needs to be serialized at the end of the page request and deserialized at the beginning of the page request, which can be costly. To improve the performance the SessionState attempts to only deserialize what is needed by only deserialize variable when it is accessed the first time, and it only re-serializes and replaces variable which were changed. If you have alot of session variable and shove them all into one class essentially everything in your session will be deserialized on every page request that uses session and everything will need to be serialized again even if only 1 property changed becuase the class changed. Just something to consider if your using alot of session and an oop mode.

Ernie
  • 241
  • 2
  • 2
  • 4
    +1 for brining this up. If you are not using InProc for Session, then Ernie is 100% correct. InProc is very limited anyway, as it does not support webfarms and will be lost if the application re-starts. Note, by performance cost we are looking at a 20% premium in using State Server mode, and serialization costs are added on top of that. As you can imagine this can get expensive. You can avoid some of the serialization overhead by sticking to primitive types (e.g. int, string, char, byte, etc.). Custom objects will be faced with serialization. User beware. – Zack Jannsen Aug 16 '12 at 22:37
  • +1 Good point. A change that would marry the two concepts would be to have each property on this custom "session" class call the asp.net session itself instead of one big object in session. Have to do the type casting that @M4N's approach avoids, but maybe worth it if you only read some of session each time. – eol Dec 13 '13 at 14:12
12

The answers presented before mine provide apt solutions to the problem, however, I feel that it is important to understand why this error results:

The Session property of the Page returns an instance of type HttpSessionState relative to that particular request. Page.Session is actually equivalent to calling Page.Context.Session.

MSDN explains how this is possible:

Because ASP.NET pages contain a default reference to the System.Web namespace (which contains the HttpContext class), you can reference the members of HttpContext on an .aspx page without the fully qualified class reference to HttpContext.

However, When you try to access this property within a class in App_Code, the property will not be available to you unless your class derives from the Page Class.

My solution to this oft-encountered scenario is that I never pass page objects to classes. I would rather extract the required objects from the page Session and pass them to the Class in the form of a name-value collection / Array / List, depending on the case.

Cerebrus
  • 25,615
  • 8
  • 56
  • 70
3

In asp.net core this works differerently:

public class SomeOtherClass
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    private ISession _session => _httpContextAccessor.HttpContext.Session;

    public SomeOtherClass(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public void TestSet()
    {
        _session.SetString("Test", "Ben Rules!");
    }

    public void TestGet()
    {
        var message = _session.GetString("Test");
    }
}

Source: https://benjii.me/2016/07/using-sessions-and-httpcontext-in-aspnetcore-and-mvc-core/

Matty
  • 505
  • 1
  • 10
  • 16
1

I had the same error, because I was trying to manipulate session variables inside a custom Session class.

I had to pass the current context (system.web.httpcontext.current) into the class, and then everything worked out fine.

MA

MunsterMan
  • 307
  • 1
  • 8
0

This should be more efficient both for the application and also for the developer.

Add the following class to your web project:

/// <summary>
/// This holds all of the session variables for the site.
/// </summary>
public class SessionCentralized
{
protected internal static void Save<T>(string sessionName, T value)
{
    HttpContext.Current.Session[sessionName] = value;
}

protected internal static T Get<T>(string sessionName)
{
    return (T)HttpContext.Current.Session[sessionName];
}

public static int? WhatEverSessionVariableYouWantToHold
{
    get
    {
        return Get<int?>(nameof(WhatEverSessionVariableYouWantToHold));
    }
    set
    {
        Save(nameof(WhatEverSessionVariableYouWantToHold), value);
    }
}

}

Here is the implementation:

SessionCentralized.WhatEverSessionVariableYouWantToHold = id;
Captain America
  • 1,802
  • 1
  • 19
  • 21