首页 > 解决方案 > 服务执行期间的ServiceStack操作顺序问题

问题描述

我们正在从 v3.9.64 升级 ServiceStack v5.11.0 的经典 ASP.NET 应用程序,并渴望成为 ServiceStack 的付费客户。但我们必须解决这个问题。ServiceStack 中的生命周期和操作顺序发生了变化。ServiceStack 处理的请求生命周期中的某些点HttpContext.Current尚未填充。我们所有的代码都希望设置它,因此我们必须在处理或请求中避免这种情况。以下是我们认为需要的操作顺序。

  1. 首先,HttpContext.Current必须由系统填充。
  2. 接下来,我们需要一个事件来触发我们的AppHost : AppHostBase,它允许我们初始化我们的中间层。我们目前正在尝试 AppHost.OnPreExecuteServiceFilter,但由于调用了插件,这被证明是有问题的。请继续阅读。
  3. 接下来,我们编写了一个插件来执行身份验证,该插件被添加到 AppHost.Configure 中的插件中。我们需要在第 2 步之后调用它。
  4. 然后我们希望调用我们的服务代码。
  5. 最后,我们需要调用 AppHost.OnEndRequest。

上面我们面临的问题是我们的身份验证插件在 AppHost.OnPreExecuteServiceFilter 之前被调用,所以我们的代码失败了,因为我们还没有初始化我们的中间层。所以目前第 2 步和第 3 步的顺序是错误的。我们如何解决这个问题?在填充 HttpContext.Current 之后和调用插件之前是否会触发不同的 AppHost 事件?或者我们可以将我们的插件配置为在 AppHost.OnPreExecuteServiceFilter 之后调用吗?

对此的进一步说明。在 v3.9.64 中,我们的 Global.Application_BeginRequest 和 EndRequest 事件被用于上述目的,并且一直运行良好。我确实看到这些事件是在传入的 ServiceStack 请求时触发的,但它们的发生顺序与以前不同,因此我们面临这个问题。

标签: c#asp.netservicestack

解决方案


操作顺序只是在 ServiceStack 请求中执行不同的钩子和过滤器的顺序。

OnPreExecuteServiceFilter顾名思义,就是在服务执行之前执行的过滤器。

接下来,我们编写了一个插件来执行身份验证,该插件被添加到 AppHost.Configure 中的插件中。我们需要在第 2 步之后调用它。

AppHost.Configure()仅在启动时执行一次,以配置您的 AppHost。如果您希望插件在请求期间执行逻辑,则需要注册在ServiceStack 请求管道中执行的自定义过滤器。

我们上面面临的问题是我们的身份验证插件在 AppHost.OnPreExecuteServiceFilter 之前被调用

此方法在执行服务之前执行,在此方法之后但在服务之前执行的唯一其他过滤器是服务过滤器操作请求过滤器属性。

填充 HttpContext.Current 后是否触发了不同的 AppHost 事件

HttpContext.Current在执行任何 ServiceStack Request 之前由 ASP.NET Framework 填充,这意味着它始终在ServiceStack Request pipeline中的任何过滤器之前填充。它不会被填充的主要原因是如果在运行时的请求期间没有从 ASP.NET 请求工作线程访问它。

在调用插件之前?

这是不可能回答的,因为您的问题遗漏了关于您的插件究竟在哪里注册其自定义处理程序的重要信息?即在此之前执行哪些过滤器取决于您的插件正在注册的请求过滤器。在请求期间执行不同处理程序的顺序记录在我们的操作顺序页面中。

如果您指的是您的插件Register(IAppHost),则此AppHost.Configure()操作仅在启动时执行一次,您无法HttpContext.Current在启动时访问,它仅在请求期间可用。启动初始化逻辑是您的插件将注册其请求过滤器的地方,例如,appHost.PreRequestFilters或者appHost.GlobalRequestFilters在执行 ServiceStack 服务之前的请求期间执行的过滤器。而在*ResponseFilters服务执行之后执行。

NowHttpContext.Current用于在请求上下文不可用时从单例上下文访问 ASP.NET 请求上下文,但这在 ServiceStack 中通常是不必要的,因为每个请求过滤器都可以从 ServiceStack 检索 ASP.NET 请求上下文IRequest.OriginalRequest,例如:

PreRequestFilters.Add((req, res) =>
{
    var aspReq = req.OriginalRequest as HttpRequestBase;
});

例如。在您可以访问的服务IRequestbase.Request


推荐阅读