ASP.NET HttpHandler vs IIS handler - asp.net

I've defined an HTTP Handler and added an entry in my web.config
<add verb="GET" path="TestApp/*" type="TestApp.TestHandler, TestWebApp" />
This works as I would expect EXCEPT when I encounter static resources eg JPG, PNG files
I need my handler to also handle paths like TestApp/logo.gif but it seems like IIS has the StaticHandler registered to intercept these requests
Is there any way for my ASP.NET HttpHandler to have a chance to handle requests for static resources ONLY for the path TestApp/* but letting the IIS StaticHandler handle everything else?
And yes I realize that letting IIS handle static resources with its own handler is faster and more efficient

Your handler will intercept those requests if you are running in integrated pipeline mode:
<system.webServer>
<handlers>
<add name="TestHandler" path="TestApp/*" verb="GET" type="TestApp.TestHandler, TestWebApp" />
</handlers>
</system.webServer>
If you are running in Classic Pipeline mode you will have to register an ISAPI filter in IIS in order to make those requests go through the managed handler.

You should add this to your web.config:
<modules runAllManagedModulesForAllRequests="true" />
This will ensure that even requests for static files are being passed through the .net pipeline.

Related

Serve up an aspx page in an asp.net web app using Microsoft.Owin.Host.SystemWeb (Katana)

I have .net web application which includes a reference to OWIN.
This is all working fine and is serving up an web application using OWIN happily.
I want to include in the same web application an aspx web page. Is there a way I can inform my web application not to use OWIN for a single page (or a path).
From investigation it looks like this might not be possible.
There are a couple of handler mappings which are at play.
System.Web.UI.PageHandlerFactory handles aspx pages
Microsoft.Owin.Host.SystemWeb.OwinHttpHandler handles owin request
I can add them seperately and get close to what I require
i.e:
<system.webServer>
<handlers>
<clear />
<add name="OWIN" path="test" verb="*" type="Microsoft.Owin.Host.SystemWeb.OwinHttpHandler" />
</handlers>
</system.webServer>
This will allow serve up owin stuff from a targetted path (test in mycase)
and
<system.webServer>
<handlers>
<clear />
<add name="APSX" path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory"/>
</handlers>
</system.webServer>
Will allow me serve up an aspx page - but only if the OWIN dlls are not in the bin directory.
If the OWIN dlls are present then the PageHandlerFactory will drop into OWIN handler and serve up via OWIN making. I.e. even though the OwinHttpHander is not specified, it still kicks into OWIN. I'm guessing this is built into the PageHandlerFactory code.
As far as I can tell, this means that you can never have an aspx page in the same web application which uses Katana (because it need the OWIN dlls, and then PageHandlerFactory calls into the OWIN code rather than aspx - deduced from testing rather than proved out right).

Why aspnet_isapi.dll still exists in iis7?

As far as i know asp.net has been integrated with IIS.
That is to say, asp.net runtime is always hosted in IIS7 no matter the incoming request is.
ie. An .aspx request or others static files request like .html or .jpg.
We know that in IIS6, aspnet_isapi.dll will be loaded to create asp.net runtime and run asp.net only when requests such as .aspx,.ashx arrive.
Now that asp.net has been integrated with IIS7 in "Integrated Mode" what's the usage of aspnet_isapi.dll? Is it the reason why we can still see aspnet_isapi.dll in iis7 is compatibility ?
In a nutshell, it's only for classic mode.
With classic pipeline mode the ASP.NET is plugged into the IIS request processing pipeline as an ISAPI extension - exactly the same way as it was in IIS 6. In fact, if you open %WINDIR%\system32\inetsrv\config\applicationHost.config file and locate the section inside of it you can see how IIS is configured to map ASP.NET specific requests to the aspnet_isapi.dll:
<handlers accessPolicy="Read, Script">
...
<add name="PageHandlerFactory-ISAPI-2.0"
path="*.aspx" verb="GET,HEAD,POST,DEBUG"
modules="IsapiModule"
scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll"
preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
...
</handlers>
Notice the preCondition attribute for the handler mapping. Among other things this attribute is set to classicMode, which ensures that this handler mapping only takes effect when the application pool is configured to run in classic mode.

HttpHandler not being called

I need to write a HttpHandler that will serve up JavaScript files which are embedded resources in .DLLs in my project. A reference in a view cannot directly see such a resource, so I planned to use a HttpHandler module that would intercept any request with a path /js/[file] , find a matching embedded file and return the script.
The problem is that my HttpHandler code is never called, despite trying lots of different settings in the section of web.config. I'm obviously missing something but with no error messages I cannot see what that is. All I ever get is a 404 from the static file handler.
Q1) Am I missing something obvious?
Q2) Is there a way to get IIS to tell me why it is not calling my handler?
Summary: I am testing on IIS Express (v8) for an ASP.NET MVC 4 application.
I created a simple library that implements IHttpHandler and added a reference to this in my test MVC application, and the following lines in web.config:
<system.webServer>
<validation validateIntegratedModeConfiguration="true" />
<handlers>
<add name="ejs" path="js/*" verb="*" type="EmbeddedJsHandler.EmbeddedJsHandler, EmbeddedJsHandler" preCondition="integratedMode" />
The library is there, but it is never called. Any request with /js/test.js or whatever just results in a 404 error.
So far I've tried lots of different configurations and settings in the handler code. I've tried preCondition, resourceType="Unspecified", modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll"
I've tried paths:
js/*.js
js/*
js/*.*
I've checked the integrated mode settings section (in system.webServer) is being used, and confirmed it is.
I've searched stack overflow for similar cases, and tried many of the possible solutions.. still no joy.
Heck even Jon Skeet has these sort of problems!
Why isn't my IHttpHandler being called?
Finally figured it out by accident - it was a missing routes.IgnoreRoute() in the RouteConfig.cs file - the MVC routing engine wasn't configured to ignore this path, so was passing it to the static file handler.
Doh!
Check this:
How to: Register HTTP Handlers:
To register an HTTP handler for IIS 7.0 running in Integrated Mode:
Compile the HTTP handler class and copy the resulting assembly to the Bin folder under the application's root folder.
In the application's Web.config file, create a handlers element in the system.webServer section.
The following example shows how to register an HTTP handler that responds to requests for the SampleHandler.new resource. The handler is defined as the class SampleHandler in the assembly SampleHandlerAssembly.
<configuration>
<system.webServer>
<handlers>
<add name="SampleHandler" verb="*"
path="SampleHandler.new"
type="SampleHandler, SampleHandlerAssembly"
resourceType="Unspecified" />
</handlers>
</system.webServer>
</configuration>
Note: The resourceType attribute performs the same function as the Verify file exists option in IIS manager for IIS 6.0.
For IIS 7.0 running in Integrated mode, only the registration in the handlers element is required.
I cannot tell you directly why your handler isn't working, but I will give you an example of a handler we use and works for us:
<system.webServer>
<handlers>
<add name="JS handler" path="*.js" verb="*" type="Handlers.Minifiers.JSMinify" resourceType="Unspecified" preCondition="integratedMode" />
</handlers>
</system.webServer>
We also have this segment, which is at least necessary for running in Cassini
<system.web>
<httpHandlers>
<add verb="*" path="*.js" type="Handlers.Minifiers.JSMinify" validate="false"/>
</httpHandlers>
</system.web>
If this doesn't help, have tou tried using path="/js/*"?

http handler asp.net

High I'm trying to get a http handler working in iis 7.5 on my local machine. In the mode on visual studio iis my handler works with the web config set to.
<httpHandlers>
<add verb="GET" path="ShowImages.ashx" type="achangeoftack_new_web.ShowImages" />
</httpHandlers>
but when deployed it throws errors so I've set it to
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<add name="ShowImages.ashx" verb="GET" path="~/ShowImages.ashx" type="achangeoftack_new_web.ShowImages" />
</handlers>
<validation validateIntegratedModeConfiguration="true" />
But I'm still getting no luck with the handler working. I think I've tried everything now I'm starting to pull my hair out.
If you're using an ASHX, you don't need to do the registration in your web.config, just use it like a page url e.g.
<img src="ShowImages.ashx?id=SomeImageId" />
and it'll just work. So I'd try taking those elements out of your web.config and see if that fixes your errors.
Why This Works
When you run aspnet_regiis on a machine, ASHX is one of the extensions that's registered into IIS for you.
At runtime when IIS receives a request for an ASHX file, it passes it across to ASP.NET and ASP.NET then resolves it in the same way as for a page or user control, and your code gets run.
You only need to register your handler in web.config if you've written a handler in a standalone class.

HttpHandler for static image is not getting called when file does not exist

I have httpHandler that handles the jpg file. When a request for a jpg image comes to server it is forwareded to handler. This works fine until i implemented finger printing for google page speed rule.
Now it gets called for http://static2.localnatamam.com/Uploaded/Image/Image_Haroon_ur_Rasheed_78.jpg
but not for
http://static2.localnatamam.com/Uploaded/Image/_SFP634229374826528000EFP_Image_Haroon_ur_Rasheed_78.jpg
First file exist in directory but second does not exist as the second URL is finger printed and i want to get the request in Handler but handler never gets evoked.
I think its might be IIS 7 configuration that is returning 404 rather than passing it to handler.
Please any advise or configuration that can route request to httphandler no matter if exist or not.
I am using asp.net MVC 2 with IIS 7 integreated Mode with target framework 4.0 in local enviornment so both of above URL will not open for any body.
My handler is simple IHttpHandler with the following IIS configuration
<add name="CrossDomainResourceHandler" type="MvcApplication3.HttpHandlers.CrossDomainResourceHandler" path="*.jpg" verb="*" resourceType="Unspecified" allowPathInfo="false" modules="IsapiModule" scriptProcessor="%path%\aspnet_isapi.dll"/>
Make sure you have this in your web.config file:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
</system.webServer>
runAllManagedModulesForAllRequests will tell IIS to route every request through the .net pipeline so that your module will pick this request up since by default static resources like .jpg are configured to not run through asp.net.

Resources