Можно ли получить доступ к SessionId в IHttpContext.LogRequest внутри IHttpModule - PullRequest
0 голосов
/ 07 июня 2018

Событие IHttpContext.LogRequest кажется естественным событием, которое нужно обработать, если вы хотите зарегистрировать запрос, используя собственный IHttpModule.Проблема, с которой я сталкиваюсь, заключается в том, что я хотел бы сохранить идентификатор сеанса в журнале, но он недоступен для большинства запросов при нажатии LogRequest.

Вот упрощенная версия моегокод:

public class ActivityTraceModule : IHttpModule, IRequiresSessionState, IReadOnlySessionState
{
    static Logger logger = LogManager.GetCurrentClassLogger();

    public void Init(HttpApplication context) {
        context.LogRequest += OnLogRequest;
    }

    public void OnLogRequest(Object source, EventArgs e) {
        var app = (HttpApplication)source;
        var context = app.Context;
        var sessionId = context.Session != null ? context.Session.SessionID : null;
        logger.Debug("SessionId: " + sessionId);
    }
}

Похоже, что состояние сеанса уже выпущено к моменту нажатия LogRequest, как показано на этом изображении:

ASP.NET App Lifecycle

Должен ли я использовать другое событие для ведения журнала?В идеале ответ уже должен быть полностью доступен.Или есть способ правильно получить доступ к состоянию сеанса в событии IHttpContext.LogRequest, о котором я не знаю?

1 Ответ

0 голосов
/ 18 июня 2018

Ну, я действительно не нашел способа получить доступ к Session запроса из события LogRequest, поэтому я просто подписался на другое событие:

public void Init(HttpApplication context) {
    context.PostRequestHandlerExecute += OnLogRequest;
    //context.LogRequest += OnLogRequest;
}

(я знаюЯ ленивый, я не изменил имя обработчика событий, но это потому, что я бы предпочел, чтобы оно означало, что оно делает, а не какое событие к нему прикреплено :-))

После этогоЯ был в состоянии получить доступ к сеансу для каждого запроса, который имел фактический сеанс.

Однако я столкнулся с еще одной «проблемой»: ASP.NET повторно использует идентификатор сеанса, сохраненный в файле cookie, для последующих запросов, даже после выхода пользователя из системы.Поскольку я хотел использовать идентификатор сеанса для «группировки» каждого «сеанса входа в систему» ​​каждого пользователя, мне пришлось очистить идентификатор сеанса, чтобы принудительно использовать новый.Для этого я создал метод расширения, чтобы отменить сеанс и очистить его идентификатор сеанса:

public static void AbandonAndClearSessionCookie(this HttpSessionState session) {
    session.Clear();
    session.Abandon();
    if (HttpContext.Current != null && HttpContext.Current.Response != null)
        HttpContext.Current.Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
}

Примечание: Этот метод не является надежным, и имя файла cookie идентификатора сеанса можно изменить вweb.config файл.Я в основном обязательно улучшу предыдущий код.

Тогда было важно использовать его, когда пользователь вышел из системы:

protected void HeadLoginStatus_LoggingOut(object sender, System.Web.UI.WebControls.LoginCancelEventArgs e) {
    Session.AbandonAndClearSessionCookie();
}

Я просто прикрепил обработчик событийк событию HeadLoginStatus.LoggingOut.

В ASP.NET MVC мне пришлось написать его по методу AuthController.Logout:

public ActionResult Logout() {
    FormsAuthentication.SignOut();
    Session.AbandonAndClearSessionCookie();
    return RedirectToAction("Index", "Home");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...