我已经完成了dotnet core 2.2的会话配置,但是仍然会为每个包含Session.Id的请求创建一个新会话。 因此,我不能将会话用作数据持有人。
我想将会话与ShoppingCart结合使用。
为此,我创建了一个单独的API项目,一个单独的Service项目和一个SPA项目。
这是ConfigureServices方法
public void ConfigureServices(IServiceCollection services)
{
services.AddAutoMapper();
// DbContext using SQL Server Provider
services.AddDbContext<ICleanTasteDbContext, CleanTasteDbContext>(options =>
{
options.UseSqlServer(
Configuration.GetConnectionString("TasteConnection"),
m => m.MigrationsAssembly("Taste.Persistence")
);
});
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);
options.Cookie.IsEssential = true;
options.Cookie.HttpOnly = true;
});
services.AddHttpContextAccessor();
// custome services
services.AddTransient<ICartService<ICart>, CartService>();
// MVC
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
// Cors
services.AddCors();
services.AddSpaStaticFiles(config =>
{
config.RootPath = "wwwroot";
});
}
这是Configure方法
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseHsts();
}
app.UseCors(x =>
x.AllowAnyHeader()
.AllowAnyMethod()
.AllowAnyOrigin()
.AllowCredentials()
);
app.UseAuthentication();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseSession();
app.UseMvc(routes =>
{
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "fallback", action = "index" }
);
});
app.UseSpa(spa =>
{
if (env.IsDevelopment())
{
spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");
}
});
}
在CartsController中,该服务的调用方式如下
var cart = await cartService.Add(product);
在CartService类IHttpContextAccessor中注入并如下调用
var cart = await httpContext.HttpContext.Session.Get<CartModel>(SESSION_NAME);
httpContext.HttpContext.Session.Set<CartModel>(SESSION_NAME, cart);
设置正确,但是在下一个请求中,有一个会话的新实例,并且再次为空。
我在做什么错了?
这与我使用不同的项目有关吗?
答案 0 :(得分:0)
很难说,但是有两个潜在的问题:
您正在使用内存中的会话,这意味着您受进程限制。会话永远不会在两个不同的项目之间共享,因为每个项目都是一个独立的运行进程,具有自己的内存支持。此外,当应用程序停止运行时,存储在内存中的所有内容都将随之消失,因此,例如,如果停止并重新启动调试,甚至只是重新构建调试程序,会话都会再见。没有真正的“分布式”内存缓存。这只是使用内存的IDistributedCache
的实现,但不是真正分布式的。
即使您拥有真正分布的会话存储,默认情况下,每个应用程序也会在其中占据自己的位置,这意味着仍不会共享。您需要确保两个应用程序都使用相同的数据保护密钥环位置,并且两个应用程序都设置了相同的应用程序名称。