首页 文章

ASP.NET核心2.1会话

提问于
浏览
7

在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 回答

  • 11

    解决方案是将会话cookie标记为必要 .

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

    有关旗帜的文件说明:

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

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

  • 1

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

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

    其次,您可以在开发中简单地使用持久性存储(您应该已经设置为在 生产环境 中使用持久性存储,因此请尽快修复,如果没有) . 您可以在开发中使用SQL Server或Redis之类的东西,就像在 生产环境 中一样 . SQL存储可以添加到现有的开发数据库中,因此您不必存储't actually need to install SQL Server. You can also install a local copy of Redis and just run it off of localhost, if you prefer that route. With either approach, your distributed cache, and your sessions along with it, will be stored in something external to the application, so starting and stopping your application will have no effect on what' .

  • 6

    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; // Default is true, make it false
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });
    

相关问题