#c# #session #asp.net-core
#c# #сессия #asp.net-core
Вопрос:
У меня есть ASP.NET Основное веб-приложение, которое использует сеанс для хранения некоторых переменных. Локально все работает нормально в любом сценарии, но по какой-то причине я не могу получить значения из сеанса в какой-то момент (они равны нулю) на компьютере Azure.
Сценарий:
- Выполнение входа в систему, который перенаправляет на другой контроллер (сохранение пользовательских данных в сеансе)
- Введите некоторые необходимые данные, а затем перенаправьте на другой контроллер (также сохраняя некоторые данные в сеансе и извлекая другие значения)
- На странице индекса задайте дополнительные данные для сеанса. Представление этого контроллера вызывает функцию javascript, которая вызывает «OnScrollEnd«, которая является методом, реализованным этим контроллером.
- Когда пользователь прокручивает страницу вниз, вызывается та же функция javascript (которая вызывает OnScrollEnd)
- Этот метод пытается извлечь данные из сеанса, но теперь его значение равно null.
(приведенный выше сценарий демонстрирует, что по существу состояние сеанса работает, но в какой-то момент ему не удается получить значения)
Журнал:
2019-04-23 14:12:34,220 [29] ИНФОРМАЦИЯ Microsoft.AspNetCore.Авторизация.DefaultAuthorizationService [(null)] <(null)> — Авторизация прошла успешно. 2019-04-23 14:12:34,220 [29] ИНФОРМАЦИЯ Microsoft.AspNetCore.Авторизация.DefaultAuthorizationService [(null)] <(null)> — Авторизация прошла успешно. 2019-04-23 14:12:34,220 [29] ИНФОРМАЦИЯ Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker [(null)] <(null)> — Выполнение метода действия MyWebService.Контроллеры.AllCardsController.OnScrollEnd (MyWebService) — Состояние проверки: действительное 2019-04-23 14:12:34,220 [29] ИНФОРМАЦИЯ Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker [(null)] <(null)> — Выполнение метода действия MyWebService.Контроллеры.AllCardsController.OnScrollEnd (MyWebService) — Состояние проверки: действительное 2019-04-23 14:12:34,220 [29] ИНФОРМАЦИЯ Microsoft.AspNetCore.Session.DistributedSession [(null)] <(null)> — Доступ к сеансу с истекшим сроком действия, ключ: c691acb5-f9ed-5a71-6ebb-f3a0980c4efd 2019-04-23 14:12:34,220 [29] ИНФОРМАЦИЯ Microsoft.AspNetCore.Session.DistributedSession [(null)] <(null)> — Доступ к сеансу с истекшим сроком действия, ключ: c691acb5-f9ed-5a71-6ebb-f3a0980c4efd 2019-04-23 14:12:34,221 [29] ИНФОРМАЦИЯ Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker [(null)] <(null)> — Выполнено действие MyWebService.Контроллеры.AllCardsController.OnScrollEnd (MyWebService) через 0,7545мс 2019-04-23 14:12:34,221 [29] ИНФОРМАЦИЯ Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker [(null)] <(null)> — Выполнено действие MyWebService.Контроллеры.AllCardsController.OnScrollEnd (MyWebService) через 0,7545мс 2019-04-23 14:12:34,223 [29] ОШИБКА Microsoft.AspNetCore.Диагностика.ExceptionHandlerMiddleware [(null)] <(null)> — При выполнении запроса произошло необработанное исключение.
(Исключение возникает из-за того, что значение, полученное из сеанса, было нулевым)
Конфигурация запуска:
public void ConfigureServices(IServiceCollection services)
{
var expiredSessionHours = Configuration.GetValue<int>("SessionExpireHours");
var expiredSessionMinutes = Configuration.GetValue<int>("SessionExpireMinutes");
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddAuthentication(options =>
{
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
options.LoginPath = "/Login";
options.ExpireTimeSpan = new TimeSpan(expiredSessionHours, expiredSessionMinutes, 0);
options.SlidingExpiration = true;
options.Cookie.Expiration = new TimeSpan(expiredSessionHours, expiredSessionMinutes, 0);
});
services.AddScoped<IUserAuthentication, AuthenticationService>();
services.AddTransient<IEncryptionService, EncryptionService>();
services.AddDbContext<DatabaseContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("myConnectionString"))
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking),
ServiceLifetime.Transient);
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
options.IdleTimeout = new TimeSpan(expiredSessionHours, expiredSessionMinutes, 0);
});
services.AddMvc(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
if (HostingEnvironment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
var supportedCultures = new[]
{
new CultureInfo("en-US"),
};
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("en-US"),
SupportedCultures = supportedCultures,
SupportedUICultures = supportedCultures
});
loggerFactory.AddLog4Net();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseSession();
app.UseAuthentication();
app.UseMvc();
}
Комментарии:
1. Вы проверили эти значения в отладчике? Истекшие сессионные часы и истекшие сессионные минуты?
2. Azure закрывает соединение, когда оно простаивает. Поэтому вам может потребоваться включить в вашем клиенте функцию Keep-Alive, которая будет периодически отправлять пустое сообщение в Azure, чтобы Azure не закрывала соединение.
3. @Jon — Да, они установлены на 1 час
4. @jdweng Как мне это сделать?
5. Не уверен, какие методы использует ваш клиент. Возможна настройка SetHandlerLifetime. Смотрите: learn.microsoft.com/en-us/aspnet/core/fundamentals /…