在 Asp.Net 的早期版本中,可以使用
在任何页面中像静态变量一样访问会话System.Web.HttpContext.Current.Session["key"]
在Asp.Net Core中,如何访问通过控制器调用的不同类中的会话,而不将会话属性作为所有类的构造函数中的附加参数传递
2017 年 1 月 17 日修订方法以修复错误
首先,我假设您已将 ASP.NET Core 应用程序配置为使用会话状态。如果没有看到@slfan的回答如何通过静态变量访问ASP.NET Core中的Session?
如何访问通过控制器调用的不同类中的会话,而不将会话属性作为所有类的构造函数中的附加参数传递
Asp.Net Core 是围绕依赖注入而设计的,通常设计者没有提供太多对上下文信息的静态访问。更具体地说,没有相当于
System.Web.HttpContext.Current
。
在控制器中,您可以通过
this.HttpContext.Session
访问会话变量,但您特别询问了如何从控制器调用的方法中访问会话而不将会话属性作为参数传递。
因此,要做到这一点,我们需要设置自己的静态类来提供对会话的访问,并且我们需要一些代码在启动时初始化该类。因为一个人可能想要静态访问整个
HttpContext
对象,而不仅仅是 Session
我采取了这种方法。
所以首先我们需要静态类:
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
方法中,可以位于该方法中的任何位置:
//Add service for accessing current HttpContext
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
接下来我们需要设置静态类,以便它可以访问 DI 容器来获取我们刚刚安装的服务。下面的代码位于 Startup.cs 文件的
Configure
方法中。该行可以位于该方法中的任何位置:
AppHttpContext.Services = app.ApplicationServices;
现在,由
Controller
调用的任何方法,即使通过异步等待模式,也可以通过 HttpContext
访问当前的
AppHttpContext.Current
因此,如果我们在
Session
命名空间中使用 Microsoft.AspNetCore.Http
扩展方法,我们可以将名为“Count”的 int
保存到会话中,如下所示:
AppHttpContext.Current.Session.SetInt32("Count", count);
从会话中检索名为“Count”的
int
可以像这样完成:
int count count = AppHttpContext.Current.Session.GetInt32("Count");
享受。
在 Startup.ConfigureServices 中您必须添加服务
services.AddSession();
并且在方法Configure中你必须使用它(重要:在
app.UseMvc()
之前调用)
app.UseSession();
现在您可以在控制器中使用它(如果从控制器派生)。可以储存
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
实例,如本 answer 中所述
如果您想从 Session 存储和检索复杂对象,您可以使用这些扩展:
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);
}
}
然后你可以这样称呼他们:
User user = new User();
user.Name = "Jignesh Trivedi";
user.Percentage = 75.45;
HttpContext.Session.SetComplexData("UserData", user);
或者,
ViewBag.data = HttpContext.Session.GetComplexData<User>("UserData");
详情请参阅https://www.c-sharpcorner.com/article/session-state-in-asp-net-core/
如果你看到这个,恭喜你,你已经找到了 7 年前(在撰写本文时)提出的问题的秘密解决方案。
有一个 nuget 包可以添加您正在寻找的功能。链接是:
说明位于页面中,但简而言之,通过添加此包并向您的program.cs 文件中添加行,您可以通过静态方法访问 Context 中的 cookie 和所有其他数据。
添加包:Microsoft.AspNetCore.SystemWebAdapters
下面是它的工作示例代码:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
// Added to enable SystemWeb
builder.Services.AddSystemWebAdapters();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseRouting();
// Added to enable SystemWeb
app.UseSystemWebAdapters();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
我的静态课程
using System.Diagnostics;
namespace WebApplication1.Models
{
public static class Test
{
public static void Run() {
string value = System.Web.HttpContext.Current.Request.Cookies["MyCookie"].Value;
Debug.WriteLine(value);
}
}
}
控制器:
using Microsoft.AspNetCore.Mvc;
using WebApplication1.Models;
namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
//HttpContext.Response.Cookies.Append("MyCookie", "Value1");
Test.Run();
return View();
}
}
}