HttpHandler with a different extension to .ashx - asp.net

I've got an image handler on my site which works on the url below. Obviously with being an asp.net httphandler it has the .ashx extension, even though it returns content with mime type image/jpeg
https://xxxxx/image.ashx?id=78164&imagelibraryid=0404fd0c-e681-4a5c-9899-f2709aaf7e0c
We want to use cloudflare for caching and serving images, but for it to work properly you have to use image urls with standard extensions i.e. jpg/gif/png etc.
Is there anyway my httphandler can detect and process any requests to image.jpeg?
Only image.jpeg should be handled by the httphandler, any other XXX.jpeg would still need to be served from the filesystem.
Is it possible?
Thanks

I think you have three options to allow you to serve the same images with a new url that looks like:
https://xxxxx/something-custom/images/78164/0404fd0c-e681-4a5c-9899-f2709aaf7e0c.jpg
Option one - use IIS rewrite rules to serve publically on one url that has proper extensions and rewrite the address inside the webserver so that the fragments get passed into the ashx handler.
Option two - use aspnet routing, originally designed for MVC, with a bunch of plumbing code to pass the data between the two paradigms, as detailed in this SO question
Option three - rewrite the code by moving it out of ashx into a new api controller as ashx handlers are a bit dated these days and mvc and model binding are often easier and more testable. Most of the core logic can probably be done quickly with lift and shift, and just use routing and mvc to map the new url fragments into variables consumed by your business logic.

Related

One custom handler for different request url's in ASP.NET web site

I am doing a small ASP.NET 2.0. site refactoring.
Currently there is the following folder structure:
/siteroot/services/home/service1
/siteroot/services/home/service2
/siteroot/services/home/service3
...
all the folders (service1, 2, 3) contain an almost identical default.aspx, with the different content hardcoded into the web form declaration.
My idea is to create one service.aspx and serve custom page (with the same template) on a particular URL request.
My question is:
How can I redirect all request to ../services/home/service1,2,3 to one particular handler/aspx page?
Preferably not to have those folders in the project structure at all, but intercept a requests that are headed to them.
If you are able to implement ASP.NET 3.5 (runs on the 2.0 CLR), then Routing sounds perfect for what you need to achieve. With this you can intercept URLs based on a particular format and then route them through to a single page or handler. You won't need a folder structure for each of your services.
Here's a few links on how to get going with it in ASP.NET WebForms. It's pretty quick to implement:
http://msdn.microsoft.com/en-us/magazine/dd347546.aspx
http://msdn.microsoft.com/en-us/library/cc668201%28v=VS.90%29.aspx
http://haacked.com/archive/2008/03/11/using-routing-with-webforms.aspx
http://weblogs.asp.net/scottgu/archive/2009/10/13/url-routing-with-asp-net-4-web-forms-vs-2010-and-net-4-0-series.aspx
One way:
Create a custom handler class that implements IHttpModule
In Init(HttpApplication application), register a method for application.AuthorizeRequest
In this method, parse ((HttpApplication)sender).Request.Path as appropriate, using HttpContext.Current.RewritePath if necessary to point to a "real" service.aspx page.
Then register your custom handler in <system.webServer><modules>.
Another way is to use the MVC-style routing, which works without MVC just fine. Details are in the answer to the question here: custom URL Routing in asp.net.

How to call a local HTTP Handler

I've got a HTTPHandler which returns either an image or some text and want to call it from the local web-app.
One way to do it would be to create a WebClient and point it at the handler and download the data that way but this will have problems when authentication is turned on in production and also doesn't seem that efficient. Is there a better way to do this?
The reason I'm trying to do this is that I have a page which injects content from other sources into panels, some of the resources are local (to the web-app) and others are remote, I wanted one solution to cover every possibility so I can change the source fairly easily.
One of the simplest way is to link the content i.e. use html elements such as image, Iframe and point their source to the handler in question. It will work with local as well as remote handlers as long as URLs are accessible from client/browser.
If you must get the content for some kind of processing etc, then you may use WebClient to download the content - it anyway support HTTP based authentication schemes (including windows/integrated authentication) so it shouldn't be an issue.
If you want to optimize the process for local handlers then you probably need to abstract the interface for content provider - you can have two implementations (one that use WebClient to get remote content and other that will probably use the native API of local handler class directly to get the content).
Extract the code from your handler to a separate assembly
Reference this assembly in the project that has HTTP Handler and make the handler just call your shared code
Reference this assembly in your web app project.
You might want to create a provider for your web app that will either use an assembly in-proc or go to a remote site.

What different customizations are possible by using HttpHandlers in an ASP.NET application?

Digging deeper into HttpHandlers I found they provide nice way to customize an ASP.NET application. I am new to ASP.NET and I want to know about different customizations that are possible using HttpHandlers. Lots of websites talk about how they are implemented but it would be nice to know some use cases beyond what ASP.NET already provides using HttpHandlers.
An ASPX page provides a base template (so to speak) for a form-based web page. By default, it outputs text/html and allows for easy adding of form elements and event handling for these elements.
In contrast, an HttpHandler is stripped to the bone. It is like a blank slate for HTTP requests. Therefore, an HttpHandler is good for many types of requests that do not necessarily require a web form. You could use an HttpHandler to output dynamic images, JSON, or many other MIME type results.
A couple examples:
1) You have a page which needs to make an AJAX call which will return a JSON response. An HttpHandler could be setup to handle this request and output the JSON.
2) You have a page which links to PDF documents that are stored as binary blobs in a database. An HttpHandler could be setup to handle this request and output the binary blob as a byte stream with a PDF MIME type for the content type.
Check this page for a good example and code of why you might want to customize them: http://dotnetslackers.com/articles/aspnet/Range-Specific-Requests-in-ASP-NET.aspx Essentially it can be used when you want to server certain files but not allow them to be accessible via a plain url (security).

Can MVC handle regular URL path requests, too?

ASP.NET MVC newbie question:
I've set up a MVC site, with a few controllers. Now my site also has a lot of content files, which are stored in a network of subfolders within my web site, and I need to be able to access them directly, e.g.
http://mydomain.com/Content/Images/Geography/Asia/Japan/TokyoAtNight.jpg
Is there a way to make this a direct pass-through to the content folder, as specified by the path, or do I have to make a Content controller that interprets the rest of the URL and returns the file as some kind of ActionResult? Bear in mind, of course, that there will be lots of different content types, not just JPEGs.
Thanks for your help!
This should work without you doing anything - static files are not processed by the routing engine.
You want to look into Routing, and IgnoreRoute specifically. Here are a couple of places to start.
Asp.Net Routing: How do I ignore multiple wildcard routes?
http://www.asp.net/mvc/tutorials/asp-net-mvc-routing-overview-cs
Take a look at the #Url.Content() helper method.
Url.Content("~Content/Images/Geography/Asia/Japan/TokyoAtNight.jpg")
Yes.
The IRouteHandler and the route registration in your global.asax is your extensibility point for configuring how MVC handles url paths.
However, by default ASP.NET MVC will allow you to access image files directly, without any additional configuration.

ASP.NET Friendly URLs

In my research, I found 2 ways to do them.
Both required modifications to the Application_BeginRequest procedure in the Global.Asax, where you would run your code to do the actual URL mapping (mine was with a database view that contained all the friendly URLs and their mapped 'real' URLs). Now the trick is to get your requests run through the .NET engine without an aspx extension. The 2 ways I found are:
Run everything through the .NET engine with a wildcard application extension mapping.
Create a custom aspx error page and tell IIS to send 404's to it.
Now here's my question:
Is there any reason one of these are better to do than the other?
When playing around on my dev server, the first thing I noticed about #1 was it botched frontpage extensions, not a huge deal but that's how I'm used to connecting to my sites. Another issue I have with #1 is that even though my hosting company is lenient with me (as I'm their biggest client) and will consider doing things such as this, they are wary of any security risks it might present.
`#2 works great, but I just have this feeling it's not as efficient as #1. Am I just being delusional?
Thanks
I've used #2 in the past too.
It's more efficient because unlike the wildcard mapping, the ASP.NET engine doesn't need to 'process' requests for all the additional resources like image files, static HTML, CSS, Javascript etc.
Alternatively if you don't mind .aspx extension in your URL's you could use: http://myweb/app/idx.aspx/products/1 - that works fine.
Having said that, the real solution is using IIS 7, where the ASP.NET runtime is a fully fledged part of the IIS HTTP module stack.
If you have the latest version of IIS there is rewrite module for it - see here. If not there are free third party binaries you can use with older IIS (i.e. version 6) - I have used one that reads the rewrite rules from an .ini file and supports regular expression but I cant remember its name sorry (its possibly this). I'd recommend this over cheaping it out with the 404 page.
You have to map all requests through the ASP.NET engine. The way IIS processes requests is by the file extension. By default it only processes the .aspx, .ashx, etc extensions that are meant to only be processed by ASP.NET. The reason is it adds overhead to the processing of the request.
I wrote how to do it with IIS 6 a while back, http://professionalaspnet.com/archive/2007/07/27/Configure-IIS-for-Wildcard-Extensions-in-ASP.NET.aspx.
You are right in doing your mapping from the database. RegEx rewriting, like is used out of the box in MVC. This is because it more or less forces you to put the primary key in the URL and does not have a good way to map characters that are not allowed in URLs, like '.
Did you checked the ASP .Net MVC Framework? Using that framework all your URLs are automatically mapped to Controllers which could perform any desired action (including redirecting to other URLs or controllers). You could also set custom routes with custom parameters. If you don't have seen it yet, maybe it will worth the look.

Resources