What's the performance difference between HttpModule and Global.aspx? - c#

I have made a web app where I am using a module which redirects without "www" urls (http://example.com/) to with "www" urls (http://www.example.com/). But as I am on shared hosting server, where I don't have permission to implement a HttpModule, then I tried the same module code with Global.asax file. That works!
I used the following (Application_BeginRequest()) event to implement my HttpModule functionality.
void Application_BeginRequest()
{
//module code
}
The module and application is working well and correctly from Global.asax file But I am worried about the performance.
Why we use the HTTPModules in asp.net If we can implement the same using Global.asax file. Is there ay performance differences between both. Or any difference about which I need to worry about when using Global.asax file instead of HttpModule ??
Please explain!

Global.asax inherits from HTTPApplication, and HTTPModules must implement the IHTTPInterface.
The HTTPModules Init method gets the HTTPApplication object passed in.
In the Init method you can hook into the events of HTTPApplication.
I would recommend to use HTTPModules wherever you can.
Especially if you make shrink-wrapped software where the customer can replace your global.asax with their own.

There is pretty much no difference. The point of HTTPModules is for clarity and seperation. Often people will pipe the request through several HTTPModules, which is something you can't get with global.asax.

Related

Application_Start vs serviceAutoStartProviders

I am using IIS7.5 to force my web app to load automatically (startMode="AlwaysRunning"), and I now want to preload my cache data. I am a bit confused though because two approaches seem identical:
use Application_Start in global.asax
use serviceAutoStartProviders in IIS config files
They seem rather redundant and doing the same thing. If they are, I guess I would rather use Application_Start than create code dependencies in IIS configuration files. Any advice?
The Application_Start in the global.asax is fired when the application receives it's first request (first user or autostart) so it is not used to start the site.
Use serviceAutoStartProviders to start
http://www.asp.net/whitepapers/aspnet4#0.2__Toc253429241
The IIS Application Warm-Up Module is easier to use
http://www.iis.net/learn/get-started/whats-new-in-iis-8/iis-80-application-initialization

When HttpModule Init method runs in ASP.NET Integrated mode?

I've written an HttpModule that is an NHibernate Session Provider. It simply opens a SessionFactory in Init method of HttpModule and gets a new Session in BeginRequest and closes it in EndRequest. At the other side, I wrote a method in Global.asax that uses a session from this HttpModule named GetData. I run that method (GetData) in Init method of Global.asax. The problem is when I use my HttpModule in integrated mode it seems that my HttpModule does not Initialize before running Init method of Global.asax.
I've searched for order of running these methods and life cycle of events but nothing useful found!
In IIS 7.x, modules and handlers should be registered within system.webServer xml element in your web.config file.
Check this MSDN article:
http://msdn.microsoft.com/en-us/library/ms227673.aspx
ASP.NET does not provide any guarantees on when HttpModule Init() methods are called with respect to one another (not unlike static initializers). In general, the Init() methods should be used to wire up event handlers, and any "real work" should be done in the event handlers.
All registered event handlers for a specific event are called from all HttpModules, including Global.asax, before moving on to the next event -- so you have control over order that way.

Confused over global.asax?

I have a class called Global that derives from HttpApplication.
Oddly, I see a lot of methods inside Global that look like:
void Application_Start(object sender, EventArgs e)
{
}
The code is definitely executing inside this method, so the method is being called from somewhere, but where? The methods aren't marked overload?
Secondly, I derived a class from Global, let's call it GlobalFoo.
Again, if I create a method called Application_Start() it will get called inside my derived class, otherwise nothing that's in Global will get called so I might as well be deriving from an empty class.
Can anyone offer any advice? Am I missing some fundamental part of ASP.NET?
so the method is being called from somewhere, but where?
This functions are called from the Application Pool (from each pool that you have assign), to signal start-up/end events of your application and help your with initializations.
Every pool that is assign to run your web application runs those functions.
asp.net is helping you create different objects/code external or not that can run together, and that's why you see that all of your registered code run. Its a help to create more than one "start up" routines that do different thinks.
This is an example, this module just check the secure protocol by him self... and you do not need to change anything on your code, just register it.
IIS calls the different Global.asax events through the asp.net isapi filter.
Perhaps this article will help explain.
The Global.asax file is an optional file used to declare and handle application and session-level events and objects for an ASP.NET web site running on an IIS Web Server
some of the key events in this file are:
Application_Init: Fires when the application initializes for the first time.
Application_Start: Fires the first time an application starts.
Session_Start: Fires the first time when a user’s session is started.
Application_BeginRequest: Fires each time a new request comes in.
Application_EndRequest: Fires when the application terminates.
Application_AuthenticateRequest: Indicates that a request is ready to be authenticated.
Application_Error: Fires when an unhandled error occurs within the application.
Session_End: Fires whenever a single user Session ends or times out.
Application_End: Fires when the application ends or times out (Typically used for application cleanup logic).
For a complete list of Global.asax events see "Global.asax Events".

IHttpHandler vs IHttpModule

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.

Posting forms to a 404 + HttpHandler in IIS7: why has all POST data gone missing?

OK, this might sound a bit confusing and complicated, so bear with me.
We've written a framework that allows us to define friendly URLs. If you surf to any arbitrary URL, IIS tries to display a 404 error (or, in some cases, 403;14 or 405). However, IIS is set up so that anything directed to those specific errors is sent to an .aspx file. This allows us to implement an HttpHandler to handle the request and do stuff, which involves finding the an associated template and then executing whatever's associated with it.
Now, this all works in IIS 5 and 6 and, to an extent, on IIS7 - but for one catch, which happens when you post a form.
See, when you post a form to a non-existent URL, IIS says "ah, but that url doesn't exist" and throws a 405 "method not allowed" error. Since we're telling IIS to redirect those errors to our .aspx page and therefore handling it with our HttpHandler, this normally isn't a problem. But as of IIS7, all POST information has gone missing after being redirected to the 405. And so you can no longer do the most trivial of things involving forms.
To solve this we've tried using a HttpModule, which preserves POST data but appears to not have an initialized Session at the right time (when it's needed). We also tried using a HttpModule for all requests, not just the missing requests that hit 404/403;14/405, but that means stuff like images, css, js etc are being handled by .NET code, which is terribly inefficient.
Which brings me to the actual question: has anyone ever encountered this, and does anyone have any advice or know what to do to get things working again? So far someone has suggested using Microsoft's own URL Rewriting module. Would this help solve our problem?
Thanks.
Microsoft released a hotfix for this :
http://support.microsoft.com/default.aspx/kb/956578
Since IIS7 uses .net from the top down there would not be any performance overhead of using an HttpModule, In fact there are several Managed HttpModules that are always used on every request. When the BeginRequest event is fired, the SessionStateModule may not have been added to the Modules collection, so if you try to handle the request during this event no session state info will be available. Setting the HttpContext.Handler property will initialize the session state if the requested handler needs it, so you can just set the handler to your fancy 404 page that implements IRequiresSessionState. The code below should do the trick, though you may need to write a different implementation for the IsMissing() method:
using System.Web;
using System.Web.UI;
class Smart404Module : IHttpModule
{
public void Dispose() {}
public void Init(HttpApplication context)
{
context.BeginRequest += new System.EventHandler(DoMapping);
}
void DoMapping(object sender, System.EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
if (IsMissing(app.Context))
app.Context.Handler = PageParser.GetCompiledPageInstance(
"~/404.aspx", app.Request.MapPath("~/404.aspx"), app.Context);
}
bool IsMissing(HttpContext context)
{
string path = context.Request.MapPath(context.Request.Url.AbsolutePath);
if (System.IO.File.Exists(path) || (System.IO.Directory.Exists(path)
&& System.IO.File.Exists(System.IO.Path.Combine(path, "default.aspx"))))
return true;
return false;
}
}
Edit: I added an implementation of IsMissing()
Note: On IIS7, The session state module does not run globally by default. There are two options: Enable the session state module for all requests (see my comment above regarding running managed modules for all request types), or you could use reflection to access internal members inside System.Web.dll.
The problem in IIS 7 of post variables not being passed through to custom error handlers is fixed in service pack 2 for Vista. Haven't tried it on Windows Server but I'm sure it will be fixed there too.
Just a guess: the handler specified in IIS7's %windir%\system32\inetsrv\config\applicationhost.config which is handling your request is not allowing the POST verb to get through at all, and it is evaluating that rule before determining whether the URL doesn't exist.
Yes, I would definitely recommend URL rewriting (using Microsoft's IIS7 one or one of the many alternatives). This is specifically designed for providing friendly URLs, whereas error documents are a last-ditch backstop for failures, which tends to munge the incoming data so it may not be what you expect.

Categories

Resources