Слишком много сеансов в таблице, предотвращающих создание нового сеанса

Я написал простую функцию, которая генерирует переменную сеанса при входе в систему и сохраняет ее в таблице Session в базе данных sql. Он работает отлично в 99% случаев, однако иногда кажется, что таблица сеансов заполняется или что-то еще, потому что страница входа будет перенаправляться на домашнюю страницу, как если бы она была правильно зарегистрирована, однако сеанс не был создан, и никакие пользовательские данные будет присутствовать на любой странице веб-приложения.

Доступ к таблице сеансов непосредственно через Sql Server Mgmt Studio и ручное удаление всех существующих сеансов под этим именем пользователя, похоже, исправляет проблему в краткосрочной перспективе, однако я хотел бы знать, что вызывает проблему, и как я могу изменить свой код, чтобы предотвратить это в будущем.

также приветствуются любые конструктивные указания о том, как улучшить мой подход

Благодаря!

Вот мой c #:

protected void CreateSession(object sender, EventArgs e) { //generate SessionId var AvailableCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyx1234567890"; var random = new Random(); var SessionId = new string(Enumerable.Repeat(AvailableCharacters, 20).Select(s => s[random.Next(s.Length)]).ToArray()); String UserIdOut = null; Session["New"] = SessionId.ToString(); string connstring = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString; using (SqlConnection conn = new SqlConnection(connstring)) { //retreive user id try { SqlCommand cmd = new SqlCommand("spInsertSessionId", conn); cmd.CommandType = System.Data.CommandType.StoredProcedure; cmd.Parameters.Add("@username", SqlDbType.VarChar).Value = tb_username.Text; cmd.Parameters.Add("@createdate", SqlDbType.VarChar).Value = DateTime.Now.ToString(); cmd.Parameters.Add("@SessionId", SqlDbType.VarChar).Value = SessionId.ToString(); conn.Open(); cmd.ExecuteNonQuery(); } catch(Exception ex) { message = "error inserting session: " + ex.Message; ClientScript.RegisterStartupScript(this.GetType(), "Popup", "ShowPopup('" + message + ex.Message + "');", true); } } } 

Вот хранимая процедура, которая вставляет идентификатор сеанса:

 CREATE PROCEDURE [dbo].[spInsertSessionId] @username VARCHAR(200) = NULL , @UserId VARCHAR(200) = NULL , @createdate VARCHAR(200) = NULL , @SessionId VARCHAR(200) = NULL AS BEGIN SELECT @UserId = user_id FROM dbo.users WHERE username = @username INSERT INTO dbo.session ( UserId , CreateDate , SessionId ) VALUES ( @userid , @createdate , @SessionId ) DELETE FROM dbo.session WHERE UserId = @UserId AND SessionId NOT IN ( SELECT TOP(5) SessionId FROM dbo.session WHERE UserId = @UserId ORDER BY CreateDate DESC ) END 

Учитывая предоставленную информацию, моя дикая догадка заключается в том, что проблема заключается в процедуре spInsertSessionId. После вставки сеанса вы удаляете «старые» сеансы, оставляя только 5 лучших, отсортированных по CreateDate DESC. Тем не менее, вы используете varchar для столбца CreateDate, и строки не гарантируются при заказе так же, как даты, если вы не используете форматы datetime, которые имеют это свойство. В вашем случае вы просто делаете DateTime.Now.ToString (), что даже зависит от вашей культуры. Таким образом, в некоторых случаях сеанс, который вы только что вставили, может быть не в верхнем 5, упорядоченном по вашим критериям, и, следовательно, удален сразу после создания. Даже если это не так – не используйте varchar для хранения дат.

Образец:

  declare @d1 varchar(max) = '10/21/2016 00:00:00'; declare @d2 varchar(max) = '10/22/2015 00:00:00'; select (case when @d1 > @d2 then 1 else 0 end) 

Здесь d1 явно ниже d2, но запрос возвращает «0». Эти даты относятся к DateTime.ToString () с инвариантной культурой.

попробуйте настроить приложение для использования <sessionState mode=SQLServer> и используйте aspnet_regsql.exe для настройки таблиц базы данных, а затем используйте коллекцию Session ["key"] для хранения данных. Тогда приложение будет управлять сеансами. И если вы не в порядке с этим, вы всегда можете написать свой собственный поставщик сеансов.

Давайте будем гением компьютера.