为什么.net Core 3.0中的ASP.NET Core Web API中的会话变为空?

时间:2019-09-26 02:13:16

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

我还在我的项目中使用该会话。它在本地主机上运行良好。发布到服务器后,如果我由邮递员发帖,则该会话有效,但如果由远程服务器发帖,则该会话不起作用。

我在Session variable value is getting null in ASP.NET Core

中发现了相同的问题

我按照上面的主题进行操作,但仍然没有效果。

这是我的代码:

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

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {            
            services.AddScoped<Global>();
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            services.Configure<GzipCompressionProviderOptions>(options => options.Level = System.IO.Compression.CompressionLevel.Optimal);
            services.AddMvc(
                options =>
            {
                options.OutputFormatters.Add(new Classes.XmlSerializerOutputFormatterNamespace());                
            }
            )
                .AddViewLocalization(Microsoft.AspNetCore.Mvc.Razor.LanguageViewLocationExpanderFormat.Suffix,
                LocalizationOptions => LocalizationOptions.ResourcesPath = "Resources").AddXmlSerializerFormatters().AddXmlDataContractSerializerFormatters();
            services.AddLocalization(options => options.ResourcesPath = "Resources");


            services.AddHttpsRedirection(options =>
            {
                options.RedirectStatusCode = StatusCodes.Status308PermanentRedirect;
                options.HttpsPort = 443;
            });
            services.AddHsts(options =>
            {
                options.Preload = true;
                options.IncludeSubDomains = true;
                options.MaxAge = TimeSpan.FromDays(60);
            });
            services.AddDistributedMemoryCache();

            services.Configure<CookiePolicyOptions>(options =>
            {
                options.CheckConsentNeeded = context => false;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });
            services.AddSession(options =>
            {                
                options.IdleTimeout = TimeSpan.FromHours(1);                           
                options.Cookie.IsEssential = true;
            });           
        }

        [Obsolete]
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");                
                app.UseHttpsRedirection();
                app.UseHsts();
            }

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

            var SupportedCultures = new List<CultureInfo> 
            {
                 new CultureInfo("en"),
                 new CultureInfo("zh-Hans"),
                 new CultureInfo("zh-Hant")
            };

            var options = new RequestLocalizationOptions
            {
                DefaultRequestCulture = new RequestCulture("zh-Hans"),
                SupportedCultures = SupportedCultures,
                SupportedUICultures = SupportedCultures,
            };
            app.UseRequestLocalization(options);
            var requestProvider = new RouteDataRequestCultureProvider();
            options.RequestCultureProviders.Insert(0, requestProvider);
            app.UseStaticFiles();

            app.UseStatusCodePagesWithReExecute("/StatusCode/{0}");

            app.UseRouting();
            app.UseAuthorization();
            app.UseSession();

            app.UseRouter(routes =>
            {
                routes.MapMiddlewareRoute("{culture=zh-hans}/{*mvcRoute}", subApp =>
                {
                    subApp.UseRequestLocalization(options);
                    subApp.UseRouting();
                    subApp.UseEndpoints(mvcRoutes =>
                    {
                        mvcRoutes.MapControllerRoute("default", "{culture=zh-hans}/{controller=Home}/{action=Index}");
                        mvcRoutes.MapControllerRoute("home.html", "{culture=zh-hans}/{controller=Home}/{action}.html");
                    });
                });
            });
        }
    }

这是控制器:

[HttpPost]
public async Task<IActionResult> abc(string i)
{
     if (HttpContext.Session.GetInt32(i) == null)
     {                
         HttpContext.Session.SetInt32(i, 1);
         _logger.LogInformation("Session is :" + HttpContext.Session.GetInt32(i).ToString());
         return Ok("First time.");
     }
     else
     {
        return Ok("Ran yet.");
     }

     return Ok(null);
}

如您所见,我已经通过记录器对控制器进行了测试。在设置&之后,返回之前,会话可以很好地工作(不仅在localhost中,而且在服务器中)。

但是,当远程服务器向服务器发布请求时,会话始终为空。

这怎么了?

1 个答案:

答案 0 :(得分:0)

我已经阅读了有关Microsoft官方教程的信息:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state?view=aspnetcore-3.0

据说:

ASP.NET Core通过向客户端提供一个包含会话ID的cookie来维护会话状态,该cookie与每个请求一起发送到应用程序。该应用使用会话ID来获取会话数据。

这意味着它需要cookie才能获取会话。简而言之,我的项目只需要获取/设置带有到期时间的静态变量,因此我认为我应该最好使用会话。现在,我认为我不需要在项目中使用Cookie。

在文章结尾,我注意到另一件事:内存缓存https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-3.0

然后我测试使用内存缓存来替换会话。好吧,它运作良好。