Сохранение данных сеанса / состояния между несколькими запросами в инфраструктуре стека служб - PullRequest
1 голос
/ 13 апреля 2020

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

Эта сторонняя служба отвечает обратно на службу обратного вызова. В этой службе обратного вызова я хотел бы использовать созданную мной переменную сеанса.

Я попытался создать переменную сеанса с помощью HttpContext.Current, но сеанс всегда равен нулю. Я даже пытался унаследовать свой класс стека службы от IRequiresSessionState

public class CallThirdParty : IRequiresSessionState

public void Get(CallThirdParty request)
{
 HttpContext context = HttpContext.Current;
 var sessVariable = "test";
 context.Session["saveSession"] = sessVariable;
}

Но context.Session всегда нулевой? Каков наилучший способ создать переменную сеанса в стеке служб или сохранить состояние для одного запроса HttpRequest?

1 Ответ

1 голос
/ 13 апреля 2020

Сеансы ServiceStack - это реализация, совершенно отличная от ASP. NET Сеансов, которые вы пытаетесь использовать здесь.

Для хранения информации о пользовательских сеансах в неаутентифицированных запросах вы можете используйте ServiceStack's SessionBag .

Если вы хотите использовать ASP. NET Сеансы в ServiceStack, вы можете включить ASP. NET Сеансы через пользовательский HttpHandlerFactory

namespace MyApp
{
    public class SessionHttpHandlerFactory : IHttpHandlerFactory
    {
        private static readonly HttpHandlerFactory Factory = new HttpHandlerFactory();

        public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string path)
        {
            var handler = Factory.GetHandler(context, requestType, url, path);
            return handler == null ? null : new SessionHandlerDecorator((IHttpAsyncHandler)handler);
        }

        public void ReleaseHandler(IHttpHandler handler) => Factory.ReleaseHandler(handler);
    }

    public class SessionHandlerDecorator : IHttpAsyncHandler, IRequiresSessionState
    {
        private IHttpAsyncHandler Handler { get; set; }

        internal SessionHandlerDecorator(IHttpAsyncHandler handler) => Handler = handler;

        public bool IsReusable => Handler.IsReusable;

        public void ProcessRequest(HttpContext context) => Handler.ProcessRequest(context);

        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) => 
          Handler.BeginProcessRequest(context, cb, extraData);

        public void EndProcessRequest(IAsyncResult result) => Handler.EndProcessRequest(result);
    }
}

Затем замените существующую регистрацию ServiceStack.HttpHandlerFactory на вышеописанную реализацию, например:

<system.web>
  <httpHandlers>
    <add path="*" type="MyApp.SessionHttpHandlerFactory, MyApp" verb="*"/>
  </httpHandlers>
</system.web>

Это для недавнего ServiceStack v4.5 +, для более старых версий вы Вам нужно будет использовать Syn c Handler Factory .

...