Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Session 如何通过静态变量访问ASP.NET Core中的会话?_Session_Asp.net Core_Asp.net Core Mvc - Fatal编程技术网

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

Session 如何通过静态变量访问ASP.NET Core中的会话?,session,asp.net-core,asp.net-core-mvc,Session,Asp.net Core,Asp.net Core Mvc,在早期版本的Asp.Net中,可以在任何页面中访问会话,就像使用静态变量一样 System.Web.HttpContext.Current.Session["key"] 在Asp.Net Core中,如何访问通过控制器调用的不同类中的会话,而不将会话属性作为所有类的构造函数中的附加参数传递给Startup.ConfigureServices中的 services.AddSession(); 在方法配置中,您必须使用它(重要提示:在app.UseMvc()之前调用) 现在,您可以在控制器中使用

在早期版本的Asp.Net中,可以在任何页面中访问会话,就像使用静态变量一样

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

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

services.AddSession();
在方法配置中,您必须使用它(重要提示:在
app.UseMvc()之前调用)

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

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
时,还可以使用
SetString
SetInt32

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
实例,如本修订方法1/17/17中所述,以修复bug

首先,我假设您已将ASP.NET核心应用程序配置为使用会话状态。如果没有看到@slfan的答案

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

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

在控制器中,您可以通过
this.HttpContext.Session
访问会话变量,但您特别询问了如何通过控制器调用的方法访问会话,而不将会话属性作为参数传递

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

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

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容器以获得我们刚刚安装的服务。下面的代码位于Startup.cs文件的
Configure
方法中。该行可以位于该方法中的任何位置:

//Add service for accessing current HttpContext
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();    
AppHttpContext.Services = app.ApplicationServices; 
现在,由
控制器调用的任何方法,即使是通过异步等待模式,也可以通过
AppHttpContext.current

因此,如果我们在
Microsoft.AspNetCore.Http
命名空间中使用
Session
扩展方法,我们可以将名为“Count”的
int
保存到Session,操作如下:

AppHttpContext.Current.Session.SetInt32("Count", count);
int count count = AppHttpContext.Current.Session.GetInt32("Count");
User user = new User();  
user.Name = "Jignesh Trivedi";  
user.Percentage = 75.45;             

HttpContext.Session.SetComplexData("UserData", user); 
从会话中检索名为“Count”的
int
,可以这样做:

AppHttpContext.Current.Session.SetInt32("Count", count);
int count count = AppHttpContext.Current.Session.GetInt32("Count");
User user = new User();  
user.Name = "Jignesh Trivedi";  
user.Percentage = 75.45;             

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

享受

如果要从会话中存储和检索复杂对象,可以使用以下扩展:

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);
    }
}
或者

ViewBag.data=HttpContext.Session.GetComplexData(“用户数据”);

有关详细信息,请参见

阅读文档如何?在ASP.NET Core的这一阶段已经做了很好的描述:在我在该站点看到的所有示例中,我只能看到作为参数传递给方法/委托的“HttpContext-objContext”对象,而会话是作为objContext.session访问的。我认为像早期的Asp.Net、HttpContext.Current.Session之类的东西一样,可以通过某种方式使用,这样就可以避免在您有权访问HttpContext的控制器中传递额外的参数(如果控制器派生自
controller
基类)否则,您必须注入
IHttpContextAccessor
@Ron C伟大的答案。通知他人,替换
等待下一步()等待下一步。Invoke()
在Core 1.0中,如果我不知道数据字节[]的大小,我该怎么办?@user8128167你不知道字节数组的大小是什么意思?在.NET中,数据数组的大小总是已知的。或者我误解了你的问题?我的意思是,如果我要调用“HttpContext.Session.TryGetValue(“key”,out data)”;“那么我不应该知道根据“key”从会话中获取值所需的数据的字节大小吗?”@user8128167否,因为“data”是out参数,所以将分配字节数组。如果必须事先知道存储数据的大小,那就太愚蠢了。你通常在不同的控制器/操作中读取会话日期。好的,我完全错过了“out”关键字,谢谢。如果您将var data=newbyte[]{},您的答案可能会更清楚;而不是“var data=newbyte[]{1,2,3,4};”?