Net 6 using session in a custom class

Jim Whitaker 21 Reputation points
2021-12-16T04:17:30.797+00:00

I can easily work with session in a page model like:

            string SessionKeyName = "logged";
            if (string.IsNullOrEmpty(HttpContext.Session.GetString(SessionKeyName)))
            {
                HttpContext.Session.SetString(SessionKeyName, "notlogged");
                //ViewData["mt"] = "notlogged";
                Response.Redirect("./login");
            }

But if I try to use session in a custom class I get an error:

Severity Code Description Project File Line Suppression State
Error CS0120 An object reference is required for the non-static field, method, or property 'HttpContext.Session' RazorPagesMovie C:\Users\Owner\source\repos\RazorPagesMovie\RazorPagesMovie\Helpers\Chk.cs 20 Active

How would I implement session in a custom class?

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,207 questions
0 comments No comments
{count} votes

Accepted answer
  1. Bruce (SqlWork.com) 56,931 Reputation points
    2021-12-17T17:33:46.683+00:00

    it would be simpler to just pass session to the class:

    using Microsoft.AspNetCore.Http;
     using Microsoft.AspNetCore.Mvc;
     using Microsoft.AspNetCore.Session;
    
    
     namespace RazorPagesMovie.Helpers
     {
         public class Chk
         {
             ISession session;
    
             public Chk(ISession session)
             {
                 this.session = session;
             }
    
             public void Foo()
             {
                 session?.SetString("Name", "Bobby");
                 session?.SetInt32("Age", 773);
             }
    
             public void getFoo()
             {
                 session?.GetString("Name");
                 session?.SetInt32("Age", 773);
             }
         }
     }
    

    in a page you create

    Chk chk = new Chk(HttpContext.Session);

    or create a session extension class

    public static class SessionExtensions
    {
         public static string? GetFoo (this ISession session) => return session["foo"];
         public static void SetFoo(this ISession session, string value) => session["foo"] = value; 
    }
    

    and use

    var foo = HttpContext.Session?.GetFoo();

    1 person found this answer helpful.
    0 comments No comments

9 additional answers

Sort by: Most helpful
  1. Jaliya Udagedara 2,736 Reputation points MVP
    2021-12-16T08:23:28.94+00:00

    In that case, you need to be using IHttpContextAccessor.

    In the Startup,

    public void ConfigureServices(IServiceCollection services)  
    {  
         // other code  
         services.AddHttpContextAccessor();  
    }  
    

    And then in your class, inject the IHttpContextAccessor.

    public class MyClass  
    {  
        private readonly IHttpContextAccessor _httpContextAccessor;  
      
        public MyClass(IHttpContextAccessor httpContextAccessor)  
        {  
            _httpContextAccessor = httpContextAccessor;  
        }  
      
        public void MyMethod()  
        {  
            HttpContext httpContext = _httpContextAccessor.HttpContext;  
           // TODO: use httpContext   
        }  
    }  
    

    More read: Access HttpContext in ASP.NET Core

    1 person found this answer helpful.
    0 comments No comments

  2. Zhi Lv - MSFT 32,021 Reputation points Microsoft Vendor
    2021-12-17T03:19:58.16+00:00

    Hi @Jim Whitaker ,

    One error Warning CS8600 Converting null literal or possible null value to non-nullable type.

    For the CS8600 warning, this issue relates the Asp.net 6 enabled the nullable reference types:

    By utilizing the new Nullable feature in C# 8, ASP.NET Core can provide additional compile-time safety in the handling of reference types. For example, protecting against null reference exceptions. Projects that have opted in to using nullable annotations may see new build-time warnings from ASP.NET Core APIs.

    So, it will show the CS8600 warning. To remove this warning, you can use the following methods:

    1. Add the suppress in source:
          public class MyClass  
          {  
              private readonly IHttpContextAccessor _contextAccessor;  
      
              public MyClass(IHttpContextAccessor httpContextAccessor)  
              {  
                  _contextAccessor = httpContextAccessor;  
              }  
      
              public string?  getValue(string mykey)  
              {  
      #pragma warning disable CS8602 // Dereference of a possibly null reference.  
      #pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.  
                  string testvalue = _contextAccessor.HttpContext.Session.GetString(mykey);  
      #pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type.  
      #pragma warning restore CS8602 // Dereference of a possibly null reference.  
      
                  return testvalue;  
              }  
          }  
      
    2. Disable the nullable reference types.

    Change the Nullable property from enable to disabled, after modifying the result (.csproj file)as below:

          <PropertyGroup>  
            <TargetFramework>net6.0</TargetFramework>  
            <Nullable>disabled</Nullable>  
            <ImplicitUsings>enable</ImplicitUsings>  
          </PropertyGroup>  
    

    Second, to get the data from a session, you need to use the GetString() method (based on your code, you are storing string values), instead of the Get() method, you can refer the following sample code:

    Class:

    namespace Core6MVCapp.Models  
    {  
        public class MyClass  
        {  
            private readonly IHttpContextAccessor _httpContextAccessor;  
      
            public MyClass(IHttpContextAccessor httpContextAccessor)  
            {  
                _httpContextAccessor = httpContextAccessor;  
            }  
      
            public string?  getValue(string mykey)  
            {  
    #pragma warning disable CS8602 // Dereference of a possibly null reference.  
    #pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.  
                string testvalue = _httpContextAccessor.HttpContext.Session.GetString(mykey);  
    #pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type.  
    #pragma warning restore CS8602 // Dereference of a possibly null reference.  
      
                return testvalue;  
            }  
        }   
    }  
    

    Program.cs:

    using Core6MVCapp.Models;  
      
    var builder = WebApplication.CreateBuilder(args);  
      
    // Add services to the container.  
    builder.Services.AddControllersWithViews();  
    builder.Services.AddDistributedMemoryCache();  
    //session  
    builder.Services.AddSession(options =>  
    {  
        options.IdleTimeout = TimeSpan.FromMinutes(10);  
        options.Cookie.HttpOnly = true;  
        options.Cookie.IsEssential = true;  
    });  
    //httpcontextaccessor  
    builder.Services.AddHttpContextAccessor();  
    builder.Services.AddScoped<MyClass>();  
      
    var app = builder.Build();  
    
    ...  
    

    Core6MVCapp.csproj: if you have added the suppress in source, there is no need to change the Nullable property.

    <Project Sdk="Microsoft.NET.Sdk.Web">  
      
      <PropertyGroup>  
        <TargetFramework>net6.0</TargetFramework>  
        <Nullable>disabled</Nullable>  
        <ImplicitUsings>enable</ImplicitUsings>  
      </PropertyGroup>  
    

    Controller:

        public class HomeController : Controller  
        {  
            private readonly ILogger<HomeController> _logger;  
            public const string SessionKeyName = "_Name";  
            public const string SessionKeyAge = "_Age";   
            private readonly MyClass _myclass;  
    
            public HomeController(ILogger<HomeController> logger, MyClass myClass)  
            {  
                _logger = logger;  
                _myclass = myClass;  
            }  
    
            public IActionResult Index()  
            {  
                if (string.IsNullOrEmpty(HttpContext.Session.GetString(SessionKeyName)))  
                {  
                    HttpContext.Session.SetString(SessionKeyName, "The Doctor");  
                    HttpContext.Session.SetInt32(SessionKeyAge, 73);  
                }  
                var name = HttpContext.Session.GetString(SessionKeyName);  
                var age = HttpContext.Session.GetInt32(SessionKeyAge).ToString();  
    
               var result =  _myclass.getValue(SessionKeyName);  
                return View();  
            }  
    
            public IActionResult Privacy()  
            {  
                var result = _myclass.getValue(SessionKeyName);  
                return View();  
            }  
    

    The output is like this:

    Result 1: Add the suppress in source:

    158442-1.gif

    Result 2: Disable the nullable reference types.

    158360-2.gif

    Update:

    It seems that you want to access the class in Razor page, if that is the case, the code should like this:

    using Core6MVCapp.Models;         // the MyClass class is in the Models folder.  
    using Microsoft.AspNetCore.Mvc.RazorPages;  
    
    namespace Core6MVCapp.Pages  
    {  
        public class DefaultModel : PageModel  
        {  
            private readonly string SessionKeyName ="_Name";  
            private readonly MyClass _myClass;  
            public DefaultModel(MyClass myClass)  
            {  
                _myClass = myClass;  
            }  
            public void OnGet()  
            {  
                var result = _myClass.getValue(SessionKeyName);  
            }  
        }  
    }  
    

    Result:

    158437-3.gif


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,
    Dillion

    1 person found this answer helpful.

  3. Jim Whitaker 21 Reputation points
    2021-12-16T19:21:45.327+00:00

    Thanks for reply, I am in net 6, I added to program.cs

    IServiceCollection serviceCollection = builder.Services.AddHttpContextAccessor();
    

    And tried:

    using Microsoft.AspNetCore.Http;
    
    namespace RazorPagesMovie.Helpers
    {
        public class MyClass
        {
            private readonly IHttpContextAccessor _httpContextAccessor;
    
            public MyClass(IHttpContextAccessor httpContextAccessor)
            {
                _httpContextAccessor = httpContextAccessor;
            }
    
            public void getValue(string mykey)
            {
                HttpContext httpContext = _httpContextAccessor.HttpContext;
                string testvalue = httpContext.Session.Get(mykey);
            }
        }
    }
    

    The getValue still has errors, let me know if I need to paste errors:

    One error Warning CS8600 Converting null literal or possible null value to non-nullable type.

    Several more however.

    0 comments No comments

  4. Bruce (SqlWork.com) 56,931 Reputation points
    2021-12-16T19:40:30.8+00:00

    where is the code that creates the class?

    you really only need to use IHttpContextAccessor for middleware. if you create the class in the page code, you can just pass the current HttpContext to the constructor, or better yet just Session.

    did you setup a session middleware, and you using sync or async session (you should use async for performance).

    the warning is because httpContext.Session can be null, or .Get() can return a null. code s/b:

    string testvalue = httpContext.Session?.Get(mykey) ?? "some default value"; // non-nullable string

    or

    string? testvalue = httpContext.Session?.Get(mykey); //nullable string

    0 comments No comments