ASP.NET核心2.1会话

时间:2018-03-16 09:34:37

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

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

调试时我注意到在每个请求中会话ID都会发生变化 (HttpContex.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?}");
        });
    }
}

Program.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都会发生变化 (HttpContex.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();
    }

3 个答案:

答案 0 :(得分:18)

ConfigureServices()课程的Startup方法中,按如下方式设置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; // Default is true, make it false
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

答案 1 :(得分:6)

解决方案是将会话cookie标记为必不可少。

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

有关标志状态的文档:

  

指示此cookie对于应用程序正常运行是否必不可少。如果为true,则可以绕过同意策略检查。默认值为false。

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

答案 2 :(得分:3)

ASP.NET Core中的默认分布式缓存存储在内存中。由于会话使用分布式缓存,这意味着您的会话存储也在内存中。存储在内存中的内容是进程限制的,因此如果进程终止,存储在内存中的所有内容都会随之发生。最后,当您停止调试时,应用程序进程将终止。这意味着每次启动和停止调试时,都会有一个全新的会话存储。

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

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