【问题标题】:ASP.NET core 2.1 sessionASP.NET 核心 2.1 会话
【发布时间】:2018-03-16 09:34:37
【问题描述】:

在 ASP.NET core 2.1 中,我无法访问会话变量。

在调试时我注意到在每个请求中会话 ID 都会更改 (HttpContext.Session.Id)

我是不是在会话配置中出错了?

Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        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);
        // Adds a default in-memory implementation of IDistributedCache.
        services.AddDistributedMemoryCache();

        services.AddSession(options =>
        {
            // Set a short timeout for easy testing.
            options.IdleTimeout = TimeSpan.FromSeconds(1000);
            options.Cookie.HttpOnly = true;
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseSession();
        if (env.IsDevelopment())
        {
            app.UseBrowserLink();
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseCookiePolicy();

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

程序.cs

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

在调试时我注意到在每个请求中会话 id 都会发生变化 (HttpContext.Session.Id)

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using ucms6.Models;

namespace ucms6.Controllers
{
public class HomeController : Controller
{
    const string SessionKeyName = "_Name";
    const string SessionKeyYearsMember = "_YearsMember";
    const string SessionKeyDate = "_Date";
    public IActionResult Index()
    {
        // Requires using Microsoft.AspNetCore.Http;
        HttpContext.Session.SetString(SessionKeyName, "Rick");
        HttpContext.Session.SetInt32(SessionKeyYearsMember, 3);
        return RedirectToAction("SessionNameYears");
      //  return View();
    }
    public IActionResult SessionNameYears()
    {
        var name = HttpContext.Session.GetString(SessionKeyName);
        var yearsMember = HttpContext.Session.GetInt32(SessionKeyYearsMember);

        return Content($"Name: \"{name}\",  Membership years: \"{yearsMember}\"");
    }
    public IActionResult About()
    {
        ViewData["Message"] = "Your application description page.";

        return View();
    }

【问题讨论】:

    标签: asp.net asp.net-core-2.1


    【解决方案1】:

    Startup类的ConfigureServices()方法中,设置options.CheckConsentNeeded = context =&gt; 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; // Default is true, make it false
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });
    

    【讨论】:

    • 谢谢它的工作,但为什么默认代码是真的?干什么用的?
    • 我猜测为什么 CheckConsentNeeded 默认是 true 是为了符合 GDPR。如果您在页面顶部的同意弹出窗口中单击接受(在默认模板的情况下),您的会话 cookie 将按您预期的方式开始工作。 GDPR 规定了 cookie 的操作方式,并且在用户同意使用它们之前不会被使用。
    【解决方案2】:

    解决方案是将会话 cookie 标记为必需。

    public void ConfigureServices(IServiceCollection services)
    {
        //...
        services.AddSession(opt =>
        {
            opt.Cookie.IsEssential = true;
        });
        //...
    }
    

    关于标志状态的文档:

    指示此 cookie 是否对于应用程序正常运行至关重要。如果为真,则可能会绕过同意策略检查。默认值为 false。

    这将保持 cookie 策略选项不变,并且会话仍按预期工作,因为 CookiePolicyOptions.CheckConsentNeeded 仅影响非必要 cookie。

    【讨论】:

    • 所以该应用仍符合 GDPR 标准?
    • @Csharpest 是的,只要您在未经同意的情况下不跟踪用户并且不保存任何个性化数据,进行会话并没有什么坏处。
    【解决方案3】:

    ASP.NET Core 中的默认分布式缓存存储在内存中。由于会话使用分布式缓存,这意味着您的会话存储也在内存中。存储在内存中的东西是进程绑定的,所以如果进程终止,存储在内存中的所有东西都会随之而来。最后,当您停止调试时,应用程序进程也将终止。这意味着每次您开始和停止调试时,您都会拥有一个全新的会话存储。

    您可以选择几条路线。首先,如果你只是想运行站点,不调试它,你可以使用CTRL+F5。这将启动 IIS Express 并加载您的 Web 应用程序,而无需同时启动所有调试机制。然后,您可以继续发出任意数量的请求,并且所有请求都将执行相同的过程(这意味着您的会话存储将保持不变)。这对于进行前端开发非常有用,因为您可以修改 Razor 视图、CSS、JS 等并查看这些更改,而无需停止并重新开始调试。但是,如果您进行任何 C# 代码更改(类、控制器等),Visual Studio 将启动构建,这将终止应用程序然后重新启动它。您的站点继续运行,就好像什么都没发生一样,但是存储在内存中的任何内容(包括您的会话)都将消失。不过,这至少比不断调试要好。

    其次,您也可以简单地在开发中使用持久性存储(您应该已经设置为在生产中使用持久性存储,所以如果没有,请尽快修复该问题)。您可以在开发中使用 SQL Server 或 Redis 之类的东西,就像在生产中一样。 SQL 存储可以添加到您现有的开发数据库中,因此您实际上不需要安装 SQL Server。如果您更喜欢该路线,您还可以安装 Redis 的本地副本并从 localhost 运行它。无论采用哪种方法,您的分布式缓存以及您的会话都将存储在应用程序外部的某个位置,因此启动和停止您的应用程序不会影响其中存储的内容。

    【讨论】:

    • 感谢您的回复。上面的代码取自 Microsft 文档(startup.cs 中的 ConfigureServices 和 Configure 除外)。所以它应该可以无缝地工作,但它仍然无法正常工作。我注意到的是,即使在单个请求中,会话 ID 在控制器操作之间也会发生变化。在上面的 homecontroller 中,会话 ID 在重定向到操作 SessionNameYears 后发生变化。你有什么想法吗?
    【解决方案4】:

    我花了一个小时试图解决这个问题,所以发布另一个解决方案以防万一。

    确保增加默认超时时间,即 10 秒。当用户填写需要大量时间的长表单时 - 如果花费的时间超过 10 秒,它可能会自行重置。

    services.AddSession(options =>
    {
        options.Cookie.IsEssential = true;
        options.IdleTimeout = TimeSpan.FromMinutes(10);
    });
    

    “默认”是指每个使用会话的 .NET 程序员都可能从this page 复制粘贴代码,并且设置为 10 秒。反正我就是这么做的。 ;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-08
      • 2017-10-22
      • 1970-01-01
      • 1970-01-01
      • 2020-02-10
      • 2018-08-22
      • 2020-07-15
      相关资源
      最近更新 更多