如何使用标准ASP。ServiceStack服务实现中的NET会话对象

时间:2022-11-16 15:15:32

I'm just getting started with ServiceStack and, as a test case, I am looking to rework an existing service which is built using standard ASP.Net handlers. I've managed to get it all working as I want it but have certain aspects which make use of the ASP.Net Session object.

我刚刚开始使用ServiceStack,作为一个测试用例,我希望重新使用使用标准ASP构建的现有服务。净处理程序。我已经设法让它按我想要的方式工作,但是有一些方面利用了ASP。净会话对象。

I've tried adding IRequiresSessionState into the service interface:

我尝试过在服务接口中添加IRequiresSessionState:

public class SessionTestService : RestServiceBase<SessionTest>, IRequiresSessionState {
    public override object OnPost(SessionTest request) {
        // Here I want to use System.Web.HttpContext.Current.Session
    }
}

The trouble is I can't seem to get it to work as the Session object is always null.

问题是我似乎不能让它工作,因为会话对象总是null。

I've done a lot of Googling and have puzzled over https://github.com/mythz/ServiceStack/blob/master/tests/ServiceStack.WebHost.IntegrationTests/Services/Secure.cs and similar but I can't find any example code which does this (which surprises me). Can anyone explain why the above doesn't work and advise what I need to do to get it working?

我做了很多搜索,并对https://github.com/mythz/servicestack/blob/masters/tests/servicestack.webhost.webhost.webhost.integrationtests/services/secure.cs等问题感到困惑,但我找不到任何实现这一点的示例代码(这让我感到惊讶)。有人能解释一下为什么上面的方法行不通吗?

Note: Ultimately I'll probably look to replace this with Redis or will try to remove any serverside session requirement, but I figured that I'd use the ASP.Net implementation for the time being, to get things working and to avoid reworking it more than is necessary at this point.

注意:最终我可能会用Redis替换它,或者尝试删除任何服务器端会话需求,但是我认为我应该使用ASP。目前的净实现,以使事情正常工作,并避免在此时重复工作。

4 个解决方案

#1


28  

Using ServiceStack ISession

使用ServiceStack ISession

ServiceStack has a new ISession interface backed by ICacheClient that lets you share same ISession between MVC Controllers, ASP.NET base pages and ServiceStack's Web Services which share the same Cookie Id allowing you to freely share data between these web frameworks.

ServiceStack有一个新的ISession接口,ICacheClient支持这个接口,它允许您在MVC controller (ASP)之间共享相同的ISession。NET base pages和ServiceStack的Web服务共享相同的Cookie Id,允许您在这些Web框架之间*地共享数据。

Note: ISession is a clean implementation that completely by-passes the existing ASP.NET session with ServiceStack's own components as described in ServiceStack's MVC PowerPack and explained in detail in the Sessions wiki page.

注意:ISession是一个干净的实现,它完全避开现有的ASP。使用ServiceStack自己的组件的NET会话,如ServiceStack的MVC PowerPack中描述的那样,并在Sessions wiki页面中详细解释。

To easily make use of ServiceStack's Session (Cache & JSON Serializer) have your Controllers inherit from ServiceStackController (in MVC) or PageBase (in ASP.NET)

要方便地使用ServiceStack的会话(缓存& JSON序列化器),必须让控制器继承ServiceStackController (MVC)或PageBase (ASP.NET)

There is also new Authentication / Validation functionality added in ServiceStack which you can read about on the wiki:

在ServiceStack中还增加了新的认证/验证功能,你可以在维基上读到:

Using ASP.NET Session

使用ASP。网络会议

Essentially ServiceStack is just a set of lightweight IHttpHandler's running on either an ASP.NET or HttpListener host. If hosted in IIS/ASP.NET (most common) it works like a normal ASP.NET request.

基本上ServiceStack只是在ASP上运行的一组轻量级IHttpHandler的集合。净或HttpListener主机。如果在IIS托管/ ASP。NET(最常见的)它工作起来像一个普通的ASP。网络请求。

Nothing in ServiceStack accesses or affects the configured Caching and Session providers in the underlying ASP.NET application. If you want to enable it you would need to configure it as per normal in ASP.NET (i.e. outside of ServiceStack) see:

ServiceStack中没有任何内容访问或影响底层ASP中配置的缓存和会话提供程序。网络应用程序。如果您想启用它,您需要按照ASP中的常规配置它。NET(即ServiceStack之外)参见:

http://msdn.microsoft.com/en-us/library/ms178581.aspx

http://msdn.microsoft.com/en-us/library/ms178581.aspx

Once configured you can access the ASP.NET session inside a ServiceStack web service via the singleton:

一旦配置好,您就可以访问ASP。通过singleton的ServiceStack web服务内部的NET会话:

HttpContext.Current.Session

Or alternatively via the underlying ASP.NET HttpRequest with:

或者通过潜在的ASP。净HttpRequest:

var req = (HttpRequest)base.RequestContext.Get<IHttpRequest>().OriginalRequest;
var session = req.RequestContext.HttpContext.Session;

Although because of the mandatory reliance on XML config and degraded performance by default, I prefer to shun the use of ASP.NET's Session, instead opting to use the cleaner Cache Clients included with ServiceStack.

尽管由于对XML配置的强制依赖和默认的性能下降,我还是倾向于避免使用ASP。NET的会话,而选择使用ServiceStack中包含的更干净的缓存客户端。

Basically the way Sessions work (ASP.NET included) is a cookie containing a unique id is added to the Response uniquely identifying the browser session. This id points to a matching Dictionary/Collection on the server which represents the browsers' Session.

基本上就是会话的工作方式(ASP)。是一个包含唯一id的cookie添加到唯一标识浏览器会话的响应中。这个id指向服务器上的一个匹配的字典/集合,它代表浏览器的会话。

The IRequiresSession interface you link to doesn't do anything by default, it simply is a way to signal to either a Custom Request Filter or base web service that this request needs to be authenticated (i.e. two places where you should put validation/authentication logic in ServiceStack).

您所链接的IRequiresSession接口默认情况下不做任何事情,它只是一个向自定义请求筛选器或base web服务发送这个请求需要认证的信号的方法(例如,您应该在ServiceStack中放置验证/认证逻辑的两个地方)。

Here's a Basic Auth implementation that looks to see if a web service is Secure and if so make sure they have authenticated.

下面是一个基本的Auth实现,它查看web服务是否安全,如果安全,请确保它们已经经过了身份验证。

Here's another authentication implementation that instead validates all services marked with an [Authenticate] attribute, and how to enable Authentication for your service by adding the Attribute on your Request DTO.

下面是另一个身份验证实现,它验证所有标有[Authenticate]属性的服务,以及如何通过在请求DTO中添加属性来启用服务的身份验证。

New Authentication Model in ServiceStack

The above implementation is apart of the multi-auth provider model included in the next version of ServiceStack. Here's the reference example showing how to register and configure the new Auth model in your application.

上述实现是ServiceStack下一个版本中包含的多身份提供者模型的一部分。下面的参考示例展示了如何在应用程序中注册和配置新的Auth模型。

Authentication Strategies

The new Auth model is entirely an opt-in convenience as you can simply not use it and implement similar behaviour yourself using Request Filters or in base classes (by overriding OnBeforeExecute). In fact the new Auth services are not actually built-into ServiceStack per-se. The entire implementation lives in the optional ServiceStack.ServiceInterfaces project and implemented using Custom Request Filters.

新的Auth模型完全是一种选择-in便利,因为您可以简单地不使用它,并使用请求过滤器或在基类中实现类似的行为(通过覆盖OnBeforeExecute)。实际上,新的Auth服务本身并没有构建到ServiceStack中。整个实现驻留在可选的ServiceStack中。serviceinterface项目,并使用自定义请求过滤器实现。

Here are different Authentication strategies I've used over the years:

下面是我多年来使用的不同身份验证策略:

  • Mark services that need authentication with an [Attribute]. Likely the most idiomatic C# way, ideal when the session-id is passed via a Cookie.

    使用[属性]标记需要身份验证的服务。可能是最惯用的c#方式,当会话-id通过Cookie传递时非常理想。

  • Especially outside of a Web Context, sometimes using a more explicit IRequiresAuthentication interface is better as it provides strong-typed access to the User and SessionId required for Authentication.

    特别是在Web上下文中之外,有时使用更显式的IRequiresAuthentication接口会更好,因为它提供对用户的强类型访问和认证所需的SessionId。

  • You can just have a 1-liner to authenticate on each service that needs it - on an adhoc basis. A suitable approach when you have very few services requiring authentication.

    您只需在特定的基础上对每个需要它的服务进行身份验证。当您只有很少的服务需要身份验证时,这是一种合适的方法。

#2


17  

That's a great and comprehensive answer by @mythz. However, when trying to access the ASP.NET session by HttpContext.Current.Session within a ServiceStack web service, it always returns null for me. That's because none of the HttpHandlers within ServiceStack are adorned with the IRequiresSessionState interface, so the .NET Framework does not provide us with the session object.

这是@mythz给出的一个伟大而全面的回答。但是,当尝试访问ASP时。净HttpContext.Current会话。ServiceStack web服务中的会话,它总是为我返回null。这是因为ServiceStack中的HttpHandlers都没有使用IRequiresSessionState接口,所以. net框架没有提供会话对象。

To get around this, I've implemented two new classes, both of which use the decorator pattern to provide us with what we need.

为了解决这个问题,我实现了两个新类,它们都使用decorator模式来提供我们需要的东西。

Firstly, a new IHttpHandler which requires session state. It wraps the IHttpHandler provided by ServiceStack and passes calls through to it...

首先,一个新的IHttpHandler需要会话状态。它封装了ServiceStack提供的IHttpHandler,并将调用传递给它…

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

    internal SessionHandlerDecorator(IHttpHandler handler) {
        this.Handler = handler;
    }

    public bool IsReusable {
        get { return Handler.IsReusable; }
    }

    public void ProcessRequest(HttpContext context) {
        Handler.ProcessRequest(context);
    }
}

Next, a new IHttpHandlerFactory which delegates the responsibility for generating the IHttpHandler to ServiceStack, before wrapping the returned handler in our new SessionHandlerDecorator...

接下来是一个新的IHttpHandlerFactory,它将生成IHttpHandler的责任委托给ServiceStack,然后在我们新的SessionHandlerDecorator中包装返回的处理程序……

public class SessionHttpHandlerFactory : IHttpHandlerFactory {
    private readonly static ServiceStackHttpHandlerFactory factory = new ServiceStackHttpHandlerFactory();

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

    public void ReleaseHandler(IHttpHandler handler) {
        factory.ReleaseHandler(handler);
    }

}

Then, it's just a matter of changing the type attributes in the handlers in Web.config to SessionHttpHandlerFactory instead of ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack, and your web services should now have the ASP.NET session avaialble to them.

然后,只需更改Web处理程序中的类型属性。配置到SessionHttpHandlerFactory而不是servicestack.webhost.endpoint。ServiceStackHttpHandlerFactory、ServiceStack以及您的web服务现在应该具有ASP。网络会话对他们是有用的。

Despite the above, I fully endorse the new ISession implementation provided by ServiceStack. However, in some cases, on a mature product, it just seems too big a job to replace all uses of the ASP.NET session with the new implementation, hence this workaround!

尽管如此,我完全支持ServiceStack提供的新ISession实现。然而,在某些情况下,在一个成熟的产品上,它看起来太大了,不能取代ASP的所有用途。NET会话与新的实现,因此这个解决方案!

#3


3  

Thanks @Richard for your answer above. I am running a new version of service stack and they have removed the ServiceStackHttpFactory with HttpFactory. Instead of having

谢谢你的回复@Richard。我正在运行一个新版本的服务堆栈,他们已经用HttpFactory删除了ServiceStackHttpFactory。而不是

private readonly static ServiceStackHttpHandlerFactory factory = new ServiceStackHttpHandlerFactory();

You need to have

你需要

private static readonly HttpHandlerFactory Factory = new HttpHandlerFactory();

Here is updated code for this service

这里是该服务的更新代码

using ServiceStack;
using System.Web;
using System.Web.SessionState;

namespace MaryKay.eCommerce.Mappers.AMR.Host
{
public class SessionHttpHandlerFactory : IHttpHandlerFactory
{
    private static readonly HttpHandlerFactory Factory = new HttpHandlerFactory();
    public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
    {
        var handler = Factory.GetHandler(context, requestType, url, pathTranslated);
        return handler == null ? null : new SessionHandlerDecorator(handler);
    }

    public void ReleaseHandler(IHttpHandler handler)
    {
        Factory.ReleaseHandler(handler);
    }
}

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

    internal SessionHandlerDecorator(IHttpHandler handler)
    {
        Handler = handler;
    }

    public bool IsReusable
    {
        get { return Handler.IsReusable; }
    }

    public void ProcessRequest(HttpContext context)
    {
        Handler.ProcessRequest(context);
    }
}
}

#4


2  

As of ServiceStack 4.5+ the HttpHandler can also support Async. Like so:

从ServiceStack 4.5+开始,HttpHandler也可以支持异步。像这样:

namespace FboOne.Services.Host
{
  public class SessionHttpHandlerFactory : IHttpHandlerFactory
  {
    private static readonly HttpHandlerFactory Factory = new HttpHandlerFactory();

    public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
    {
      var handler = Factory.GetHandler(context, requestType, url, pathTranslated);
      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
    {
      get { return Handler.IsReusable; }
    }

    public void ProcessRequest(HttpContext context)
    {
      Handler.ProcessRequest(context);
    }

    public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
    {
      return Handler.BeginProcessRequest(context, cb, extraData);
    }

    public void EndProcessRequest(IAsyncResult result)
    {
      Handler.EndProcessRequest(result);
    }
  }
}

#1


28  

Using ServiceStack ISession

使用ServiceStack ISession

ServiceStack has a new ISession interface backed by ICacheClient that lets you share same ISession between MVC Controllers, ASP.NET base pages and ServiceStack's Web Services which share the same Cookie Id allowing you to freely share data between these web frameworks.

ServiceStack有一个新的ISession接口,ICacheClient支持这个接口,它允许您在MVC controller (ASP)之间共享相同的ISession。NET base pages和ServiceStack的Web服务共享相同的Cookie Id,允许您在这些Web框架之间*地共享数据。

Note: ISession is a clean implementation that completely by-passes the existing ASP.NET session with ServiceStack's own components as described in ServiceStack's MVC PowerPack and explained in detail in the Sessions wiki page.

注意:ISession是一个干净的实现,它完全避开现有的ASP。使用ServiceStack自己的组件的NET会话,如ServiceStack的MVC PowerPack中描述的那样,并在Sessions wiki页面中详细解释。

To easily make use of ServiceStack's Session (Cache & JSON Serializer) have your Controllers inherit from ServiceStackController (in MVC) or PageBase (in ASP.NET)

要方便地使用ServiceStack的会话(缓存& JSON序列化器),必须让控制器继承ServiceStackController (MVC)或PageBase (ASP.NET)

There is also new Authentication / Validation functionality added in ServiceStack which you can read about on the wiki:

在ServiceStack中还增加了新的认证/验证功能,你可以在维基上读到:

Using ASP.NET Session

使用ASP。网络会议

Essentially ServiceStack is just a set of lightweight IHttpHandler's running on either an ASP.NET or HttpListener host. If hosted in IIS/ASP.NET (most common) it works like a normal ASP.NET request.

基本上ServiceStack只是在ASP上运行的一组轻量级IHttpHandler的集合。净或HttpListener主机。如果在IIS托管/ ASP。NET(最常见的)它工作起来像一个普通的ASP。网络请求。

Nothing in ServiceStack accesses or affects the configured Caching and Session providers in the underlying ASP.NET application. If you want to enable it you would need to configure it as per normal in ASP.NET (i.e. outside of ServiceStack) see:

ServiceStack中没有任何内容访问或影响底层ASP中配置的缓存和会话提供程序。网络应用程序。如果您想启用它,您需要按照ASP中的常规配置它。NET(即ServiceStack之外)参见:

http://msdn.microsoft.com/en-us/library/ms178581.aspx

http://msdn.microsoft.com/en-us/library/ms178581.aspx

Once configured you can access the ASP.NET session inside a ServiceStack web service via the singleton:

一旦配置好,您就可以访问ASP。通过singleton的ServiceStack web服务内部的NET会话:

HttpContext.Current.Session

Or alternatively via the underlying ASP.NET HttpRequest with:

或者通过潜在的ASP。净HttpRequest:

var req = (HttpRequest)base.RequestContext.Get<IHttpRequest>().OriginalRequest;
var session = req.RequestContext.HttpContext.Session;

Although because of the mandatory reliance on XML config and degraded performance by default, I prefer to shun the use of ASP.NET's Session, instead opting to use the cleaner Cache Clients included with ServiceStack.

尽管由于对XML配置的强制依赖和默认的性能下降,我还是倾向于避免使用ASP。NET的会话,而选择使用ServiceStack中包含的更干净的缓存客户端。

Basically the way Sessions work (ASP.NET included) is a cookie containing a unique id is added to the Response uniquely identifying the browser session. This id points to a matching Dictionary/Collection on the server which represents the browsers' Session.

基本上就是会话的工作方式(ASP)。是一个包含唯一id的cookie添加到唯一标识浏览器会话的响应中。这个id指向服务器上的一个匹配的字典/集合,它代表浏览器的会话。

The IRequiresSession interface you link to doesn't do anything by default, it simply is a way to signal to either a Custom Request Filter or base web service that this request needs to be authenticated (i.e. two places where you should put validation/authentication logic in ServiceStack).

您所链接的IRequiresSession接口默认情况下不做任何事情,它只是一个向自定义请求筛选器或base web服务发送这个请求需要认证的信号的方法(例如,您应该在ServiceStack中放置验证/认证逻辑的两个地方)。

Here's a Basic Auth implementation that looks to see if a web service is Secure and if so make sure they have authenticated.

下面是一个基本的Auth实现,它查看web服务是否安全,如果安全,请确保它们已经经过了身份验证。

Here's another authentication implementation that instead validates all services marked with an [Authenticate] attribute, and how to enable Authentication for your service by adding the Attribute on your Request DTO.

下面是另一个身份验证实现,它验证所有标有[Authenticate]属性的服务,以及如何通过在请求DTO中添加属性来启用服务的身份验证。

New Authentication Model in ServiceStack

The above implementation is apart of the multi-auth provider model included in the next version of ServiceStack. Here's the reference example showing how to register and configure the new Auth model in your application.

上述实现是ServiceStack下一个版本中包含的多身份提供者模型的一部分。下面的参考示例展示了如何在应用程序中注册和配置新的Auth模型。

Authentication Strategies

The new Auth model is entirely an opt-in convenience as you can simply not use it and implement similar behaviour yourself using Request Filters or in base classes (by overriding OnBeforeExecute). In fact the new Auth services are not actually built-into ServiceStack per-se. The entire implementation lives in the optional ServiceStack.ServiceInterfaces project and implemented using Custom Request Filters.

新的Auth模型完全是一种选择-in便利,因为您可以简单地不使用它,并使用请求过滤器或在基类中实现类似的行为(通过覆盖OnBeforeExecute)。实际上,新的Auth服务本身并没有构建到ServiceStack中。整个实现驻留在可选的ServiceStack中。serviceinterface项目,并使用自定义请求过滤器实现。

Here are different Authentication strategies I've used over the years:

下面是我多年来使用的不同身份验证策略:

  • Mark services that need authentication with an [Attribute]. Likely the most idiomatic C# way, ideal when the session-id is passed via a Cookie.

    使用[属性]标记需要身份验证的服务。可能是最惯用的c#方式,当会话-id通过Cookie传递时非常理想。

  • Especially outside of a Web Context, sometimes using a more explicit IRequiresAuthentication interface is better as it provides strong-typed access to the User and SessionId required for Authentication.

    特别是在Web上下文中之外,有时使用更显式的IRequiresAuthentication接口会更好,因为它提供对用户的强类型访问和认证所需的SessionId。

  • You can just have a 1-liner to authenticate on each service that needs it - on an adhoc basis. A suitable approach when you have very few services requiring authentication.

    您只需在特定的基础上对每个需要它的服务进行身份验证。当您只有很少的服务需要身份验证时,这是一种合适的方法。

#2


17  

That's a great and comprehensive answer by @mythz. However, when trying to access the ASP.NET session by HttpContext.Current.Session within a ServiceStack web service, it always returns null for me. That's because none of the HttpHandlers within ServiceStack are adorned with the IRequiresSessionState interface, so the .NET Framework does not provide us with the session object.

这是@mythz给出的一个伟大而全面的回答。但是,当尝试访问ASP时。净HttpContext.Current会话。ServiceStack web服务中的会话,它总是为我返回null。这是因为ServiceStack中的HttpHandlers都没有使用IRequiresSessionState接口,所以. net框架没有提供会话对象。

To get around this, I've implemented two new classes, both of which use the decorator pattern to provide us with what we need.

为了解决这个问题,我实现了两个新类,它们都使用decorator模式来提供我们需要的东西。

Firstly, a new IHttpHandler which requires session state. It wraps the IHttpHandler provided by ServiceStack and passes calls through to it...

首先,一个新的IHttpHandler需要会话状态。它封装了ServiceStack提供的IHttpHandler,并将调用传递给它…

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

    internal SessionHandlerDecorator(IHttpHandler handler) {
        this.Handler = handler;
    }

    public bool IsReusable {
        get { return Handler.IsReusable; }
    }

    public void ProcessRequest(HttpContext context) {
        Handler.ProcessRequest(context);
    }
}

Next, a new IHttpHandlerFactory which delegates the responsibility for generating the IHttpHandler to ServiceStack, before wrapping the returned handler in our new SessionHandlerDecorator...

接下来是一个新的IHttpHandlerFactory,它将生成IHttpHandler的责任委托给ServiceStack,然后在我们新的SessionHandlerDecorator中包装返回的处理程序……

public class SessionHttpHandlerFactory : IHttpHandlerFactory {
    private readonly static ServiceStackHttpHandlerFactory factory = new ServiceStackHttpHandlerFactory();

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

    public void ReleaseHandler(IHttpHandler handler) {
        factory.ReleaseHandler(handler);
    }

}

Then, it's just a matter of changing the type attributes in the handlers in Web.config to SessionHttpHandlerFactory instead of ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack, and your web services should now have the ASP.NET session avaialble to them.

然后,只需更改Web处理程序中的类型属性。配置到SessionHttpHandlerFactory而不是servicestack.webhost.endpoint。ServiceStackHttpHandlerFactory、ServiceStack以及您的web服务现在应该具有ASP。网络会话对他们是有用的。

Despite the above, I fully endorse the new ISession implementation provided by ServiceStack. However, in some cases, on a mature product, it just seems too big a job to replace all uses of the ASP.NET session with the new implementation, hence this workaround!

尽管如此,我完全支持ServiceStack提供的新ISession实现。然而,在某些情况下,在一个成熟的产品上,它看起来太大了,不能取代ASP的所有用途。NET会话与新的实现,因此这个解决方案!

#3


3  

Thanks @Richard for your answer above. I am running a new version of service stack and they have removed the ServiceStackHttpFactory with HttpFactory. Instead of having

谢谢你的回复@Richard。我正在运行一个新版本的服务堆栈,他们已经用HttpFactory删除了ServiceStackHttpFactory。而不是

private readonly static ServiceStackHttpHandlerFactory factory = new ServiceStackHttpHandlerFactory();

You need to have

你需要

private static readonly HttpHandlerFactory Factory = new HttpHandlerFactory();

Here is updated code for this service

这里是该服务的更新代码

using ServiceStack;
using System.Web;
using System.Web.SessionState;

namespace MaryKay.eCommerce.Mappers.AMR.Host
{
public class SessionHttpHandlerFactory : IHttpHandlerFactory
{
    private static readonly HttpHandlerFactory Factory = new HttpHandlerFactory();
    public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
    {
        var handler = Factory.GetHandler(context, requestType, url, pathTranslated);
        return handler == null ? null : new SessionHandlerDecorator(handler);
    }

    public void ReleaseHandler(IHttpHandler handler)
    {
        Factory.ReleaseHandler(handler);
    }
}

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

    internal SessionHandlerDecorator(IHttpHandler handler)
    {
        Handler = handler;
    }

    public bool IsReusable
    {
        get { return Handler.IsReusable; }
    }

    public void ProcessRequest(HttpContext context)
    {
        Handler.ProcessRequest(context);
    }
}
}

#4


2  

As of ServiceStack 4.5+ the HttpHandler can also support Async. Like so:

从ServiceStack 4.5+开始,HttpHandler也可以支持异步。像这样:

namespace FboOne.Services.Host
{
  public class SessionHttpHandlerFactory : IHttpHandlerFactory
  {
    private static readonly HttpHandlerFactory Factory = new HttpHandlerFactory();

    public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
    {
      var handler = Factory.GetHandler(context, requestType, url, pathTranslated);
      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
    {
      get { return Handler.IsReusable; }
    }

    public void ProcessRequest(HttpContext context)
    {
      Handler.ProcessRequest(context);
    }

    public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
    {
      return Handler.BeginProcessRequest(context, cb, extraData);
    }

    public void EndProcessRequest(IAsyncResult result)
    {
      Handler.EndProcessRequest(result);
    }
  }
}