ASP.NET Core中的会话变量值为空

45

我在一个方法中设置了一个会话变量,然后在控制器的另一个方法中尝试获取会话变量的值,但总是获取到null:

这是我的代码:

public class HomeController : Controller
{
    public IActionResult Index()
    { 
        HttpContext.Session.SetString("Test", "Hello!");
        var message = HttpContext.Session.GetString("Test");// Here value is getting correctly
        return View();
    }

    public IActionResult About()
    {
        var message = HttpContext.Session.GetString("Test"); // This value is always getting null here

        return View();
    }
}

以下是我在 Startup 类中的会话配置:

ConfigureServices() 方法中:

services.Configure<CookiePolicyOptions>(options =>
{
    // This lambda determines whether user consent for non-essential cookies is needed for a given request.
    options.CheckConsentNeeded = context => true;
    options.MinimumSameSitePolicy = SameSiteMode.None;
});

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddDistributedMemoryCache();
services.AddMvc().AddSessionStateTempDataProvider();
services.AddSession(options =>
{
    options.Cookie.Name = "TanvirArjel.Session";
    options.IdleTimeout = TimeSpan.FromDays(1);
});

Configure()方法中:

app.UseSession();
app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});

非常奇怪和特别的问题!任何帮助将不胜感激!

5个回答

85

适用于 ASP.NET Core 2.1 和 2.2

在 Startup 类的 ConfigureServices 方法中,将 options.CheckConsentNeeded = context => false; 设置如下:

services.Configure<CookiePolicyOptions>(options =>
{
  // This lambda determines whether user consent for non-essential cookies is needed for a given request.
  options.CheckConsentNeeded = context => false;
  options.MinimumSameSitePolicy = SameSiteMode.None;
});

问题已解决!


2
但是这是否意味着CheckConsentNeeded默认为false?https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.cookiepolicyoptions.checkconsentneeded?view=aspnetcore-2.2 - user8128167
10
对我没有用,还有其他什么我可以做的吗? - Love Pandey
对我来说不起作用,经过几次重定向后,会话就会结束,我需要重新登录。 - Leon Barkan
这个答案和 app.UseSession(); 帮助我掌握了会话,谢谢。 - vandsh
这是一种不好的方法。这将使您的网站/应用程序不符合GDPR。请查看Max Favilli的答案。这将解决您的问题并仍然提示用户同意。 - Sal Alturaigi
显示剩余6条评论

11

你也可以按照这里的说明,仅需设置Cookie.IsEssential = true即可:https://andrewlock.net/session-state-gdpr-and-non-essential-cookies/

services.AddSession()有一个重载,允许你在Startup文件中配置SessionOptions。你可以更改各种设置,如会话超时时间,并且你还可以自定义会话cookie。要将cookie标记为必需的,请将IsEssential设置为true:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => true; // consent required
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddSession(opts => 
    {
        opts.Cookie.IsEssential = true; // make the session cookie Essential
    });
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

我在控制器之间失去了值,使用上述代码应该会出现这种情况吗? - c-sharp-and-swiftui-devni

3

我曾经遇到过同样的问题,尝试了以下方法,发现其中任意一种都有效!

 1. options.CheckConsentNeeded = context => false;
 2. opts.Cookie.IsEssential = true; // make the session cookie Essential

然而,虽然不是很确定,但我认为选项#1可能会潜在地导致违反GDPR规定。因此我更倾向于选择选项#2。


0

这可能是前端配置问题。

您遇到的会话问题可能是由于您的前端应用程序的配置引起的。如果您正在使用一个单独的前端应用程序(例如Angular、React或Vue.js)与ASP.NET Core API进行交互,请确保发送到API的HTTP请求包括处理会话所需的信息(并在浏览器中保存cookie)。

如果您在Postman或Swagger中使用两个请求之间持久化会话,那么这很可能就是问题所在。

即,在Angular前端上修复此问题,您必须在请求的HttpClient选项中添加以下内容:{ withCredentials: true }


-1

我尝试添加Microsoft关于session的文档中提到的代码行,但没有起作用。

从HttpContext.Session的代码中可以看出,在同一请求中可以使用Session。 HttpContext.Session

因此,最后我创建了一个静态类,如下所示,它在整个应用程序中都可以使用Session。

public static class SessionHelper
    {
        private static IDictionary<string, string> Session { get; set; } = new Dictionary<string, string>();

        public static void setString(string key, string value)
        {
            Session[key] = value;
        }

        public static string getString(string key)
        {
            return Session.ContainsKey(key) ? Session[key] : string.Empty;
        }
    }

用法:

在一个请求中设置字符串

SessionHelper.setString("UserId", "123");

在另一个请求中读取字符串

SessionHelper.getString("UserId");

希望能对你有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接