Подтвердить что ты не робот

Может ли промежуточное ПО OWIN использовать сеанс http?

У меня было немного кода, который я дублировал для ASP.NET и SignalR, и я решил переписать его как промежуточное ПО OWIN, чтобы удалить это дублирование.

Как только я запускал его, я заметил, что HttpContext.Current.Session имеет значение NULL, и я не видел объект сеанса на IOwinContext, который имеет мое промежуточное ПО.

Можно ли получить доступ к сеансу http из OWIN?

4b9b3361

Ответ 1

Да, но это довольно взломать. Он также не будет работать с SignalR, потому что SignalR ДОЛЖЕН запускаться до того, как будет получен сеанс, чтобы предотвратить длительные блокировки сеанса.

Сделайте это, чтобы включить сеанс для любого запроса:

public static class AspNetSessionExtensions
{
    public static IAppBuilder RequireAspNetSession(this IAppBuilder app)
    {
        app.Use((context, next) =>
        {
            // Depending on the handler the request gets mapped to, session might not be enabled. Force it on.
            HttpContextBase httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
            httpContext.SetSessionStateBehavior(SessionStateBehavior.Required);
            return next();
        });
        // SetSessionStateBehavior must be called before AcquireState
        app.UseStageMarker(PipelineStage.MapHandler);
        return app;
    }
}

Затем вы можете получить доступ к сеансу с помощью HttpContext.Current.Session или

HttpContextBase httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);

Ответ 2

Этот ответ является ремиксом из начального ответа, поэтому его суть следует отнести к @Tratcher. Это достаточно различно, хотя публиковать его отдельно, вместо того, чтобы предлагать редактирование.


Предположим, что вы хотите сделать небольшое приложение OWIN для базовых целей тестирования (например, в качестве заглушки/подделки для большего API при выполнении интеграционных тестов), в том числе немного хакильный способ использования состояния сеанса, будет работать нормально.

Прежде всего, вам понадобятся:

using Microsoft.Owin;
using Microsoft.Owin.Extensions;
using Owin;

С помощью них вы можете создать вспомогательный метод:

public static void RequireAspNetSession(IAppBuilder app)
{
    app.Use((context, next) =>
    {
        var httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
        httpContext.SetSessionStateBehavior(SessionStateBehavior.Required);
        return next();
    });

    // To make sure the above `Use` is in the correct position:
    app.UseStageMarker(PipelineStage.MapHandler);
}

Вы также можете создать это как метод расширения, как это сделал оригинальный ответ.

Обратите внимание, что если вы не используете UseStageMarker, вы столкнулись бы с этой ошибкой:

Ошибка сервера в приложении "/".
"HttpContext.SetSessionStateBehavior" может быть вызван только до того, как событие HttpApplication.AcquireRequestState будет поднято.

В любом случае, с приведенным выше, вы теперь можете использовать HttpContext в своем приложении OWIN следующим образом:

public void Configuration(IAppBuilder app)
{
    RequireAspNetSession(app);

    app.Run(async context =>
    {
        if (context.Request.Uri.AbsolutePath.EndsWith("write"))
        {
            HttpContext.Current.Session["data"] = DateTime.Now.ToString();
            await context.Response.WriteAsync("Wrote to session state!");
        }
        else
        {
            var data = (HttpContext.Current.Session["data"] ?? "No data in session state yet.").ToString();
            await context.Response.WriteAsync(data);
        }
    });
}

Если вы запускаете IIS Express с помощью этого небольшого приложения, вы сначала получите:

В сеансе еще нет данных.

Затем, если вы перейдете к http://localhost:12345/write, вы получите:

Написал состояние сеанса!

Затем, если вы вернетесь/зайдите на любой другой URL-адрес этого хоста, вы получите:

11/4/2015 10:28:22 AM

Или что-то подобное.