简体   繁体   中英

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. But we must resolve this problem. The lifecycle and order of operations has changed in ServiceStack. There are certain points in the lifecycle of a request as handled by ServiceStack where HttpContext.Current is not yet populated. 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.
  2. Next, we need an event to fire on our AppHost: AppHostBase that allows us to initialize our middle tier. We are currently trying AppHost.OnPreExecuteServiceFilter, but this is proving problematic due to the invocation of Plugins. Please read on.
  3. Next, we have a Plugin we have written to do authentication that is added to Plugins in AppHost.Configure. We need this to be invoked AFTER Step 2.
  4. Then we want our Service code to be invoked.
  5. Finally, we need AppHost.OnEndRequest to be invoked.

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. So Step 2 and 3 are occurring in the wrong order currently. How do we fix this? Is there a different AppHost event that is fired after HttpContext.Current is populated, and before Plugins are invoked? Or can we configure our plugin to be invoked just after 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. 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.

The Order of Operations is simply the order in which different hooks and filters are executed within a ServiceStack Request.

OnPreExecuteServiceFilter is as the name says a filter that's executed just before a Service is executed.

Next, we have a Plugin we have written to do authentication that is added to Plugins in AppHost.Configure. We need this to be invoked AFTER Step 2.

AppHost.Configure() is executed only once on Startup for the purposes of configuring your 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 .

The problem we face above is that our authentication Plugin is being invoked BEFORE 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 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 . 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.

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. 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. Whereas the *ResponseFilters are executed after a Service is executed.

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:

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

E,g. within a Service you can access IRequest from base.Request .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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