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.
First, HttpContext.Current must be populated by the system.
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.
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.
Then we want our Service code to be invoked.
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? i.e. 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, e.g. 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, e.g:
PreRequestFilters.Add((req, res) =>
{
var aspReq = req.OriginalRequest as HttpRequestBase;
});
E,g. within a Service you can access IRequest from base.Request.
Related
I have one application that sends a GET request to another application.
This request is generated once, and sent once. I have validated this by generating a System.Net.HttpWebRequest object, populating it, and debugging my workflow until I call request.GetResponse(). This is only called once.
In the application that recieves the request, I have overriden the AuthenticationHandler's HandleAuthenticateAsync method with some custom authentication logic. When I debug the request, my validation works, and I return a valid AuthenticateResult. However, immediately after this returned, my app goes into the HandleAuthenticateAsync a second time. This time the request is missing the Authentication header, and the app therefore returns a 401 response.
Does anyone have any clue what might be wrong here?
Found it. The answer for me was to remove app.UseHttpsRedirection(); from Startup.cs' Configure method, since I was calling this application through http://localhost for testing purposes.
I have a class library I developed that is rather processing intensive that I currently call through a WCF REST service.
The REST service directly accesses the DLLs for the class library and more or less the WCF rest service is an interface for the system.
Let's say the following methods are defined:
Create Request
Starts a thread that takes five minutes, but immediately returns a session ID that the process generates and the thread uses to report when it is completed to the database.
Check Status
Accepts a session id and checks the database to see if the process has completed.
I have to think that there is a better way to "manage" the threads running, however, my requirements state that the user should receive an immediate response from the REST service upon issuing a request.
I am using the WCF Message property to return XML to the browser and as this application can be called from any programming language I can't use classic WCF and callbacks (I think, correct me if I am wrong).
Sometimes I run into an issue where an error occurs and the iscomplete event never gets written to the database and therefore the "Check Status" method says it's processing forever.
Does anyone have any ideas about what is normally done and what can be done in this situation?
Thanks!
Jeffrey Kevin Pry
Your service should return a 202 Accepted at the initial request with a way for the client to check the current status, either through the Location header or as part of the content.
As you indicate the client then polls the URL indicated to check the current status. I would also suggest adding a bit of cache time to this response in case a client just starts looping.
How you handle things on the server is up to you and in no way related to REST. For one thing I would put all logic that executes as the background thread in a try/catch to you can return an error status back if an error occurs and possibly retry the action depending on the circumstances.
I implemented a similiar process for importing/processing of large files and to be honest, I have never had a problem. Perhaps resolving the reason that the IsComplete never gets set will make this more resilient.
Not much of an answer, but still..
I've the following doubt. I've a page "MyPage" and i've declared few dictionary objects in the page class.
My doubt is
If i declare the dictionary as a private non-static object i'm not able to use it across the functions in that page class (the object is getting nulled)
But if i declare the dictionary to be static i'm able to across the object across the functions. But will that object be same across all the users who have opened the page right now (guessing that each user will have an instance of the page in turn has an instance for the page class and static variables of a class are invariable across all the instances of the class)
Is my understanding right? How to declare the object to be available across all the functions within the page class and unique for each instance of the page (user).
Update1
Okie, i find that the initialization of the dictionary object in the page class is done in a different thread (WCF Duplex callback). But in the main page thread the dictionary object is still remaining as null (uninitialized). Any ideas?
Update2
Marshalling - useful by any chance?
Update3
In reply to John-
Thanks for your reply. The problem i'm facing now is to pass the data from the WCF callback class at the client side(which will be invoked in a separate thread) to the asp.net page. So how can i do that? View state may help me to persist the data across requests. But when the callback is invoked by the server notifying for a change how should i pass the changes (data) to the UI thread (asp.net page)?
Don't do things like this.
If you need to maintain data between pages, use Session state. That's what it's for. You should remember that you get a new instance of your page class on every request. Do not use statics to keep changing data around for subsequent requests. You will probably get into trouble with multiple requests updating the data at the same time.
You can't do things like this with ASP.NET!
You seem to be treating this as though it were a desktop program - as though your class instance and all state will still be there for you next time you execute a method on the page. That's not true - when the request is complete, your page will be Disposed. Nothing about the page will remain valid.
In particular, if the callback doesn't happen before the request ends, then the callback method had better not reference anything having to do with the request, like your page. That's because the callback might fire after the request is already over! The state is corrupt or worse.
Unless you are going to have the page wait for the callback, you'd really better not use them in your pages. Instead, create a separate Windows Service or something and have it issue the requests and await the callback. The page can then use Ajax or something to ask if the request is complete, and to get the response once complete.
If you think you heard me say to call back to an ASP.NET page, then you misunderstood.
Create a Windows Service. Your Windows Service will host a WCF service that the ASP.NET application will talk to. The WCF Service will keep track of things like who's joined a chat, who's typing, etc.
The web application cannot be notified when something interesting happens. Instead, the web application will have to poll the WCF service, asking if anything interesting has happened. When something happens, the WCF service will pass the "something" back to the ASP.NET application (or possibly, back to the page, called by AJAX).
I misspoke earlier. You simply cannot use a callback contract at all in this situation. It's not like the web pages are like a desktop application, one per user, waiting to be notified. They're more like a desktop application where, when the user makes a request, you take his PC and give him a new one just like it, before the response arrives.
You are right in the second case. In your first case I'm guessing you mean that if a user clicks multiple controls on your page then the event handlers are seeing that the dictionary is null (instead of having the result from the previous event handler).
Remember that every request on a page (even from the same user) creates a new instance of your page class. That means that each time a request starts, your dictionary will be null. The only way for a variable to maintain its value between subsequent requests is to persist it server-side (for example, in user-specific session information on the server) or to push it to the client with the page content so that it can be part of the subsequent request data (so it's stored in ViewState or other storage at the client's browser between requests).
Rereading this question, there are three seperate state machines, and none of them are being coupled together - hence the problem :)
State of the "user state" - these are the key/value pairs in the dictionary, their lifetime spans multiple page requests and callbacks
State of a "page", which needs to consume the data from "user state". Pages are destroyed after each and every page request.
State of the "service call" which needs to populate the data in "user state" Service calls are generally destroyed after each invocation.
There are a few strategies that could enable you to couple the systems:
ViewState such that the state machine for "user state" is sent down as part of the state of the page, and sent back on postbacks. This may constrain how you perform service callbacks
Session such that the state machine for "user state" is stored server side, and can be accessed by key.
Static dictionary of user states, where the key for the outer dictionary would be the identity of the "user state", where the 1st page request would create the "user state" entry, and you'd need to manage teardown. (v.similar to session - though works without ASP.NET).
There are lots of nuances to each solution - I'd advise light reading :)
you are right that a static member will be the same for all instances of the page, and thus all individual users. You need to make it a non-static member if you want to access it from every method in the class. You should look into why the object is null. Are you properly instantiating it at the proper time?
How can we use global.asax in asp.net? And what is that?
MSDN has an outline of the purpose of the global.asax file.
Effectively, global.asax allows you to write code that runs in response to "system level" events, such as the application starting, a session ending, an application error occuring, without having to try and shoe-horn that code into each and every page of your site.
You can use it by by choosing Add > New Item > Global Application Class in Visual Studio. Once you've added the file, you can add code under any of the events that are listed (and created by default, at least in Visual Studio 2008):
Application_Start
Application_End
Session_Start
Session_End
Application_BeginRequest
Application_AuthenticateRequest
Application_Error
There are other events that you can also hook into, such as "LogRequest".
Global asax events explained
Application_Init: Fired when an application initializes or is first called. It's invoked for all HttpApplication object instances.
Application_Disposed: Fired just before an application is destroyed. This is the ideal location for cleaning up previously used resources.
Application_Error: Fired when an unhandled exception is encountered within the application.
Application_Start: Fired when the first instance of the HttpApplication class is created. It allows you to create objects that are accessible by all HttpApplication instances.
Application_End: Fired when the last instance of an HttpApplication class is destroyed. It's fired only once during an application's lifetime.
Application_BeginRequest: Fired when an application request is received. It's the first event fired for a request, which is often a page request (URL) that a user enters.
Application_EndRequest: The last event fired for an application request.
Application_PreRequestHandlerExecute: Fired before the ASP.NET page framework begins executing an event handler like a page or Web service.
Application_PostRequestHandlerExecute: Fired when the ASP.NET page framework is finished executing an event handler.
Applcation_PreSendRequestHeaders: Fired before the ASP.NET page framework sends HTTP headers to a requesting client (browser).
Application_PreSendContent: Fired before the ASP.NET page framework sends content to a requesting client (browser).
Application_AcquireRequestState: Fired when the ASP.NET page framework gets the current state (Session state) related to the current request.
Application_ReleaseRequestState: Fired when the ASP.NET page framework completes execution of all event handlers. This results in all state modules to save their current state data.
Application_ResolveRequestCache: Fired when the ASP.NET page framework completes an authorization request. It allows caching modules to serve the request from the cache, thus bypassing handler execution.
Application_UpdateRequestCache: Fired when the ASP.NET page framework completes handler execution to allow caching modules to store responses to be used to handle subsequent requests.
Application_AuthenticateRequest: Fired when the security module has established the current user's identity as valid. At this point, the user's credentials have been validated.
Application_AuthorizeRequest: Fired when the security module has verified that a user can access resources.
Session_Start: Fired when a new user visits the application Web site.
Session_End: Fired when a user's session times out, ends, or they leave the application Web site.
The Global.asax file, also known as
the ASP.NET application file, is an
optional file that contains code for
responding to application-level and
session-level events raised by ASP.NET
or by HTTP modules.
http://msdn.microsoft.com/en-us/library/2027ewzw.aspx
Global.asax is the asp.net application file.
It is an optional file that handles events raised by ASP.NET or by HttpModules. Mostly used for application and session start/end events and for global error handling.
When used, it should be in the root of the website.
The root directory of a web application has a special significance and certain content can be present on in that folder.
It can have a special file called as “Global.asax”. ASP.Net framework uses the content in the global.asax and creates a
class at runtime which is inherited from HttpApplication.
During the lifetime of an application, ASP.NET maintains a pool of Global.asax derived HttpApplication instances. When
an application receives an http request, the ASP.Net page framework assigns one of these instances to process that
request. That instance is responsible for managing the entire lifetime of the request it is assigned to and the instance
can only be reused after the request has been completed when it is returned to the pool.
The instance members in Global.asax cannot be used for sharing data across requests but static member can be.
Global.asax can contain the event handlers of HttpApplication object and some other important methods which
would execute at various points in a web application
The Global.asax can be used to handle events arising from the application. This link provides a good explanation: http://aspalliance.com/1114
My question is simple (although the answer will most likely not be): I'm trying to decide how to implement a server side upload handler in C# / ASP.NET.
I've used both HttpModules (IHttpModule interface) and HttpHandlers (IHttpHandler interface) and it occurs to me that I could implement this using either mechanism. It also occurs to me that I don't understand the differences between the two.
So my question is this: In what cases would I choose to use IHttpHandler instead of IHttpModule (and vice/versa)?
Is one executed much higher in the pipeline? Is one much easier to configure in certain situations? Does one not work well with medium security?
An ASP.NET HTTP handler is the process (frequently referred to as the "endpoint") that runs in response to a request made to an ASP.NET Web application. The most common handler is an ASP.NET page handler that processes .aspx files. When users request an .aspx file, the request is processed by the page through the page handler. You can create your own HTTP handlers that render custom output to the browser.
Typical uses for custom HTTP handlers include the following:
RSS feeds To create an RSS feed for a Web site, you can create a handler that emits RSS-formatted XML. You can then bind a file name extension such as .rss to the custom handler. When users send a request to your site that ends in .rss, ASP.NET calls your handler to process the request.
Image server If you want a Web application to serve images in a variety of sizes, you can write a custom handler to resize images and then send them to the user as the handler's response.
An HTTP module is an assembly that is called on every request that is made to your application. HTTP modules are called as part of the ASP.NET request pipeline and have access to life-cycle events throughout the request. HTTP modules let you examine incoming and outgoing requests and take action based on the request.
Typical uses for HTTP modules include the following:
Security Because you can examine incoming requests, an HTTP module can perform custom authentication or other security checks before the requested page, XML Web service, or handler is called. In Internet Information Services (IIS) 7.0 running in Integrated mode, you can extend forms authentication to all content types in an application.
Statistics and logging Because HTTP modules are called on every request, you can gather request statistics and log information in a centralized module, instead of in individual pages.
Custom headers or footers Because you can modify the outgoing response, you can insert content such as custom header information into every page or XML Web service response.
From: http://msdn.microsoft.com/en-us/library/bb398986.aspx
As stated here, HttpModules are simple classes that can plug themselves into the request processing pipeline, whereas HttpHandlers differ from HttpModules not only because of their positions in the request processing pipeline, but also because they must be mapped to a specific file extensions.
IHttpModule gives you much more control, you can basically control all of the traffic directed to your Web application. IHttpHandler gives you less control (the traffic is filtered before it reaches your handler), but if this is sufficient for your needs, then I see no reason to use the IHttpModule.
Anyway, it's probably best to have your custom logic in a separate class, and then just use this class from either IHttpModule or IHttpHandler. This way you don't really have to worry about choosing one or the other. In fact, you could create an extra class which implements both IHttpHandler and IHttpModule and then decide what to use by setting it in Web.config.
15 seconds has a nice small tutorial giving practical example
Modules are intended to handle events raised by the application before and after the request is actually processed by the handler. Handlers, on the other hand, aren't given the opportunity to subscribe to any application events and, instead, simply get their ProcessRequest method invoked in order to the "main" work of processing a specific request.
Take a look at this documentation from Microsoft (about half way down the page in the "The request is processed by the HttpApplication pipeline" section):
http://msdn.microsoft.com/en-us/library/bb470252.aspx
You can see in step 15 where the handler gets its chance to execute. All of the events before and after that step are available for interception by modules, but not handlers.
Depending on what specific features you're trying to achieve, you could use either a handler or a module to implement an upload handler. You might even end up using both.
Something to consider might to use an upload handler that's already written.
Here's a free and open source one:
http://www.brettle.com/neatupload
Here's a commercial one:
http://krystalware.com/Products/SlickUpload/
If you look at the documentation for NeatUpload, you'll see that it requires you to configure a module.