首页 > 解决方案 > 在服务堆栈框架中的多个请求之间保存会话/状态数据

问题描述

我有一个使用多个参数调用第三方服务的请求。我想在会话中保存一个参数值以供第三方响应后使用。

该第三方服务响应回叫服务。在这个回调服务中,我想使用我创建的会话变量。

我尝试使用 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 状态的最佳方法是什么?

标签: c#.netservicestack

解决方案


ServiceStack 的 Sessions与您在此处尝试使用的 ASP.NET Sessions 完全不同。

要在未经身份验证的请求中存储自定义会话信息,您可以使用ServiceStack 的 SessionBag

如果您想在 ServiceStack 中使用 ASP.NET 会话,您可以通过自定义 HttpHandlerFactory 启用 ASP.NET 会话

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+,对于旧版本,您需要使用Sync Handler Factory


推荐阅读