web-dev-qa-db-fra.com

Session ASP.NET Core 2.1

Dans ASP.NET Core 2.1, je ne peux pas accéder aux variables de session. 

Lors du débogage, j'ai remarqué que dans chaque demande, l'ID de session change (HttpContex.Session.Id) 

Ai-je commis une erreur dans la configuration de la session?

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>();
}

Lors du débogage, j’ai remarqué que dans chaque demande, l’identifiant de session change (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();
    }
10
ugur

Dans la méthode ConfigureServices() de la classe Startup, définissez options.CheckConsentNeeded = context => false; comme suit:

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;
        });
16
TanvirArjel

La solution consiste à marquer le cookie de session comme essentiel.

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

La documentation sur le drapeau indique:

Indique si ce cookie est essentiel au bon fonctionnement de l'application. Si la valeur est true, les vérifications de stratégie de consentement peuvent être ignorées. La valeur par défaut est false.

Les options de stratégie de cookie resteront intactes et la session fonctionnera toujours comme prévu car CookiePolicyOptions.CheckConsentNeeded n'affecte que les cookies non essentiels.

6
SeriousM

Le cache cache distribué par défaut dans ASP.NET Core est en mémoire. Comme les sessions utilisent le cache distribué, cela signifie que votre magasin de session est également en mémoire. Les choses stockées en mémoire sont liées au processus, donc si le processus se termine, tout ce qui est stocké en mémoire va de pair. Enfin, lorsque vous arrêtez le débogage, le processus d'application est terminé. Cela signifie que chaque fois que vous démarrez et arrêtez le débogage, vous disposez d'un tout nouveau magasin de session.

Vous pouvez emprunter deux itinéraires. Tout d’abord, si vous voulez juste exécuter le site, sans le déboguer, vous pouvez utiliser CTRL+F5. Ceci lancera IIS Express et chargera votre application Web sans démarrer toutes les machines de débogage. Vous pouvez ensuite procéder à autant de demandes que vous le souhaitez et le processus sera le même (ce qui signifie que votre magasin de session sera intact). C'est très bien pour faire du développement en front, car vous pouvez modifier vos vues Razor, CSS, JS, etc. et voir ces modifications sans avoir à arrêter et à relancer le débogage. Toutefois, si vous apportez des modifications de code C # (classe, contrôleur, etc.), Visual Studio lancera une construction qui mettra fin à l'application, puis la redémarrera. Votre site continue de fonctionner comme si de rien n'était, mais tout ce qui est stocké en mémoire, y compris vos sessions, disparaîtra. C'est au moins mieux que de déboguer constamment.

Deuxièmement, vous pouvez également utiliser simplement un magasin persistant en développement (vous devez déjà être configuré pour utiliser un magasin persistant en production, donc corrigez-le dès que possible, sinon). Vous pouvez utiliser quelque chose comme SQL Server ou Redis en développement, comme vous le feriez en production. Le magasin SQL peut être ajouté à votre base de développement existante, vous n'avez donc pas besoin d'installer SQL Server. Vous pouvez également installer une copie locale de Redis et simplement l'exécuter à partir de localhost, si vous préférez cette route. Quelle que soit l’approche choisie, votre cache distribué et vos sessions seront stockés dans un élément externe à l’application. Par conséquent, le démarrage et l’arrêt de votre application n’auront aucun effet sur ce qui y est stocké.

1
Chris Pratt