简体   繁体   English

服务执行期间的 ServiceStack 操作顺序问题

[英]ServiceStack order of operations problem during the execution of a Service

We are upgrading our classic ASP.NET application for ServiceStack v5.11.0 from v3.9.64 and are eager to become a paying customer of ServiceStack.我们正在将经典的 ASP.NET 应用程序从 v3.9.64 升级到 ServiceStack v5.11.0,并渴望成为 ServiceStack 的付费客户。 But we must resolve this problem.但是我们必须解决这个问题。 The lifecycle and order of operations has changed in ServiceStack. ServiceStack 中的生命周期和操作顺序发生了变化。 There are certain points in the lifecycle of a request as handled by ServiceStack where HttpContext.Current is not yet populated.在由 ServiceStack 处理的请求生命周期中,有某些点HttpContext.Current尚未填充。 All of our code expects that to be set up, so we must avoid that in our processing or a request.我们所有的代码都希望设置它,因此我们必须在我们的处理或请求中避免这种情况。 Below is the order of operations that we think we need.以下是我们认为需要的操作顺序。

  1. First, HttpContext.Current must be populated by the system.首先, HttpContext.Current必须由系统填充。
  2. Next, we need an event to fire on our AppHost: AppHostBase that allows us to initialize our middle tier.接下来,我们需要在我们的AppHost: AppHostBase允许我们初始化我们的中间层。 We are currently trying AppHost.OnPreExecuteServiceFilter, but this is proving problematic due to the invocation of Plugins.我们目前正在尝试 AppHost.OnPreExecuteServiceFilter,但由于调用了插件,这被证明是有问题的。 Please read on.请继续阅读。
  3. Next, we have a Plugin we have written to do authentication that is added to Plugins in AppHost.Configure.接下来,我们编写了一个插件来执行身份验证,该插件已添加到 AppHost.Configure 中的插件中。 We need this to be invoked AFTER Step 2.我们需要在第 2 步之后调用它。
  4. Then we want our Service code to be invoked.然后我们希望我们的服务代码被调用。
  5. Finally, we need AppHost.OnEndRequest to be invoked.最后,我们需要调用 AppHost.OnEndRequest。

The problem we face above is that our authentication Plugin is being invoked BEFORE AppHost.OnPreExecuteServiceFilter, and so our code fails because we have not initialized our middle tier yet.我们上面面临的问题是我们的身份验证插件在 AppHost.OnPreExecuteServiceFilter 之前被调用,因此我们的代码失败,因为我们还没有初始化我们的中间层。 So Step 2 and 3 are occurring in the wrong order currently.因此,当前第 2 步和第 3 步的顺序错误。 How do we fix this?我们如何解决这个问题? Is there a different AppHost event that is fired after HttpContext.Current is populated, and before Plugins are invoked?在填充 HttpContext.Current 之后和调用插件之前是否会触发不同的 AppHost 事件? Or can we configure our plugin to be invoked just after AppHost.OnPreExecuteServiceFilter?或者我们可以将我们的插件配置为在 AppHost.OnPreExecuteServiceFilter 之后调用吗?

Further notes on this.关于这一点的进一步说明。 With v3.9.64 our Global.Application_BeginRequest and EndRequest events were being used for the above purpose, and that was always working fine.在 v3.9.64 中,我们的 Global.Application_BeginRequest 和 EndRequest 事件被用于上述目的,并且始终运行良好。 I do see that these events are fired upon an incoming ServiceStack request, but they are not happening in the same order they used to, thus we face this problem.我确实看到这些事件是在传入的 ServiceStack 请求时触发的,但它们的发生顺序与过去不同,因此我们面临这个问题。

The Order of Operations is simply the order in which different hooks and filters are executed within a ServiceStack Request.操作顺序只是在 ServiceStack 请求中执行不同挂钩和过滤器的顺序。

OnPreExecuteServiceFilter is as the name says a filter that's executed just before a Service is executed. OnPreExecuteServiceFilter ,就是在执行服务之前执行的过滤器。

Next, we have a Plugin we have written to do authentication that is added to Plugins in AppHost.Configure.接下来,我们编写了一个插件来执行身份验证,该插件已添加到 AppHost.Configure 中的插件中。 We need this to be invoked AFTER Step 2.我们需要在第 2 步之后调用它。

AppHost.Configure() is executed only once on Startup for the purposes of configuring your AppHost. AppHost.Configure()仅在启动时执行一次,用于配置您的 AppHost。 If you want your Plugin to execute logic during a request it needs to register a Custom Filter that's executed within the ServiceStack Request Pipeline .如果您希望插件在请求期间执行逻辑,则需要注册一个在ServiceStack Request Pipeline中执行的自定义过滤器。

The problem we face above is that our authentication Plugin is being invoked BEFORE AppHost.OnPreExecuteServiceFilter我们上面面临的问题是我们的身份验证插件在 AppHost.OnPreExecuteServiceFilter 之前被调用

This method is executed before a Service is executed, the only other filters executed after this method but before a Service are Service Filters and Action Request Filter attributes.此方法在执行服务之前执行,在此方法之后但在服务之前执行的唯一其他过滤器是服务过滤器操作请求过滤器属性。

Is there a different AppHost event that is fired after HttpContext.Current is populated填充 HttpContext.Current 后是否会触发不同的 AppHost 事件

HttpContext.Current is populated by the ASP.NET Framework before any ServiceStack Request is executed which means it's always populated before any of the filters in a ServiceStack Request pipeline . HttpContext.Current在执行任何 ServiceStack 请求之前由 ASP.NET 框架填充,这意味着它总是在ServiceStack 请求管道中的任何过滤器之前填充。 The major Reason why it wouldn't be populated is if it was not accessed from an ASP.NET Request Worker Thread during a Request at runtime.它不会被填充的主要原因是如果在运行时的请求期间没有从 ASP.NET 请求工作线程访问它。

and before Plugins are invoked?在调用插件之前?

This is impossible to answer as your question leaves out the vital information as to where exactly your plugin registers its custom handlers?这是不可能回答的,因为您的问题遗漏了关于您的插件究竟在哪里注册其自定义处理程序的重要信息? ie What filters are executed before then is dependent on what request filter your plugin is registering.即在此之前执行的过滤器取决于您的插件正在注册的请求过滤器。 The order of which different handlers are executed during a request is documented in our Order of Operations page.在我们的操作顺序页面中记录了请求期间执行不同处理程序的顺序。

If you're referring to your plugins Register(IAppHost) , this like AppHost.Configure() is only executed once on Startup, you cannot access HttpContext.Current on Startup, it's only available during a Request.如果您指的是您的插件Register(IAppHost) ,这就像AppHost.Configure()仅在启动时执行一次,您无法在启动时访问HttpContext.Current ,它仅在请求期间可用。 The Startup initialization logic is where your plugin would register its Request filters, eg appHost.PreRequestFilters or appHost.GlobalRequestFilters which are executed during a request before a ServiceStack Service is executed. Startup 初始化逻辑是您的插件将注册其请求过滤器的地方,例如appHost.PreRequestFiltersappHost.GlobalRequestFilters ,它们在执行 ServiceStack 服务之前的请求期间执行。 Whereas the *ResponseFilters are executed after a Service is executed.*ResponseFilters在服务执行后执行。

Now HttpContext.Current is for accessing an ASP.NET Request Context from a singleton context for when the Request context is not available however this is generally unnecessary in ServiceStack as every Request Filter can retrieve the ASP.NET Request Context from a ServiceStack IRequest.OriginalRequest , eg:现在HttpContext.Current用于在请求上下文不可用时从 singleton 上下文访问 ASP.NET 请求上下文,但这在 ServiceStack 中通常是不必要的,因为每个请求过滤器都可以从 ServiceStack IRequest.OriginalRequest检索 ASP.NET 请求上下文,例如:

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

E,g.例如。 within a Service you can access IRequest from base.Request .在 Service 中,您可以从base.Request访问IRequest

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM