如何通过静态变量访问ASP.NET Core中的Session?

How to access the Session in ASP.NET Core via static variable?

在早期版本的Asp.Net中,可以在任何页面(如使用静态变量)中访问会话

1
System.Web.HttpContext.Current.Session["key"]

在Asp.Net Core中,如何访问通过控制器调用的不同类中的会话,而不在所有类的构造函数中将session属性作为附加参数传递


修订方法1/17/17修复错误

首先,我假设您已将ASP.NET Core应用程序配置为使用会话状态。如果没有看到@slfan的答案如何通过静态变量访问ASP.NET Core中的Session?

How to access session in different class called via controller, without passing the session property as an additional parameter in the constructor of all classes

Asp.Net Core是围绕依赖项注入而设计的,通常,设计人员没有提供太多的静态访问上下文信息。更具体地说,没有等效于System.Web.HttpContext.Current

在Controller中,您可以通过this.HttpContext.Session访问Session var,但是您具体询问了如何在不将session属性作为参数传递的情况下,从控制器调用的方法获取对Session的访问。

因此,为此,我们需要设置自己的静态类以提供对会话的访问,并且需要一些代码在启动时初始化该类。因为一个人可能希望静态访问整个HttpContext对象,而不仅仅是Session,所以我采用了这种方法。

所以首先我们需要静态类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using Microsoft.AspNetCore.Http;
using System;
using System.Threading;

namespace App.Web {

    public static class AppHttpContext {
        static IServiceProvider services = null;

        /// <summary>
        /// Provides static access to the framework's services provider
        /// </summary>
        public static IServiceProvider Services {
            get { return services; }
            set {
                if(services != null) {
                    throw new Exception("Can't set once a value has already been set.");
                }
                services = value;
            }
        }

        /// <summary>
        /// Provides static access to the current HttpContext
        /// </summary>
        public static HttpContext Current {
            get {
                IHttpContextAccessor httpContextAccessor = services.GetService(typeof(IHttpContextAccessor)) as IHttpContextAccessor;
                return httpContextAccessor?.HttpContext;
            }
        }

    }
}

接下来,我们需要向DI容器添加一个服务,该服务可以提供对当前HttpContext的访问。此服务随Core MVC框架一起提供,但默认情况下未安装。因此,我们需要用一行代码"安装"它。该行位于Startup.cs文件的ConfigureServices方法中,可以位于该方法的任何位置:

1
2
//Add service for accessing current HttpContext
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

接下来,我们需要设置我们的静态类,以便它可以访问DI容器以获得刚刚安装的服务。下面的代码在Startup.cs文件的Configure方法中。该行可以位于该方法中的任何位置:

1
AppHttpContext.Services = app.ApplicationServices;

现在,Controller调用的任何方法,甚至通过异步等待模式,都可以通过AppHttpContext.Current访问当前的HttpContext

因此,如果我们在Microsoft.AspNetCore.Http命名空间中使用Session扩展方法,则可以像下面这样将一个名为" Count"的int保存到会话中:

1
AppHttpContext.Current.Session.SetInt32("Count", count);

从会话中检索名为" Count"的int可以像这样完成:

1
int count count = AppHttpContext.Current.Session.GetInt32("Count");

请享用。


如果要从Session中存储和检索复杂对象,则可以改用以下扩展名:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static class SessionExtensions
{
    public static void SetObjectAsJson(this ISession session, string key, object value)
    {
        session.SetString(key, JsonConvert.SerializeObject(value));
    }

    public static T GetObjectFromJson< T >(this ISession session, string key)
    {
        var data = session.GetString(key);  
        if (data == null)  
        {  
            return default(T);  
        }  
        return JsonConvert.DeserializeObject< T >(data);
    }
}

然后,您将这样称呼他们:

1
2
3
4
5
User user = new User();  
user.Name ="Jignesh Trivedi";  
user.Percentage = 75.45;            

HttpContext.Session.SetComplexData("UserData", user);

要么,

1
ViewBag.data = HttpContext.Session.GetComplexData<User>("UserData");

有关详细信息,请参阅https://www.c-sharpcorner.com/article/session-state-in-asp-net-core/


在Startup.ConfigureServices中,您必须添加服务

1
services.AddSession();

并在配置方法中必须使用它(重要:在app.UseMvc()之前调用)

1
app.UseSession();

现在,您可以在控制器中使用它(如果从Controller派生)。你可以存储

1
2
3
4
5
var data = new byte[] { 1, 2, 3, 4 };
HttpContext.Session.Set("key", data); // store byte array

byte[] readData;
HttpContext.Session.TryGetValue("key", out readData); // read from session

导入名称空间Microsoft.AspNetCore.Http时,也可??以使用SetStringSetInt32

1
2
3
4
5
6
using Microsoft.AspNetCore.Http;

HttpContext.Session.SetString("test","data as string"); // store string
HttpContext.Session.SetInt32("number", 4711); // store int

int ? number = HttpContext.Session.GetInt32("number");

在控制器外部,您无权访问HttpContext,但可以注入IHttpContextAccessor实例,如此答案中所述