How to make a Control that's also a HttpHandler?
In the Photo Album Handler, one of our goals is to have everything in a single file for easy deployment (we still need an additional separate dll in version 2.1 but we're getting there). I also wanted the handler to be able to act like a Control so that it can be integrated in an existing site. Even when used in control mode, the handler part is still necessary to serve the thumbnail and preview versions of the images. We also want to enable the handler just by dropping it into the image directory without having to modify or create a web.config file, which forces us to use a .ashx file.
So how can a single file and even a single class describe both a HttpHandler and a Control?
The first idea that comes to mind is to just implement a WebControl that also implements IHttpHandler. The only way to reference the control in a page would be to use a @Reference directive with a virtual path to force the compilation of the ashx file and to make its types available to the page. Unfortunately, this doesn't work because the types in question will not be available at parse-time, which is when we'll need them if we're going to use the declarative ASP.NET syntax on the page (it works fine if you only need to instantiate the control through imperative code). The solution is to derive from UserControl instead of Control or WebControl. User controls can be referenced and still work at parse-time. The Album is not essentially a user control, but a user control being a Control itself, it does the job. I sealed the class, though, so that nobody has the weird idea to create a .ascx file that derives from it.
This all works perfectly well, but there's still one problem to solve. In Visual Studio's design view, the file will be mistaken for a regular .ascx file and the designer will show the handler's source code instead of any useful design view. I don't think there's a way to make the design view be actually useful for this kind of control (it is, after all, pertty hacky), but we can make things behave a little better by tricking the design view. At the beginning of the .ashx file, I added a comment in the form of:
// <b>This is what will be displayed in the design view</b><!--
This way, the design view will ignore the rest of the file (the source code) as it seems to be in an HTML comment. Of course, I also have the following line at the end of the file:
// -->
to end the comment.