Monday, 3 April 2006
Having a) implemented a comments feed b) as a handler (pat self on back), I thought it would be "elegant" to deliver it as URL that ended in .rss. And so I have: the comment feed is now BlogCommentsFeed.rss. Check it out:
It wasn't hard, but I had to bang on the side of the box a few times before everything was working. What it really was was a lesson in how much ASP.NET does for you under the covers.
I started with a default handler (BlogCommentsFeed.ashx). The .ashx extension is, haha, handled automatically by ASP.NET; ASP.NET assumes that it's dealing with an HTTP handler. Alls you have to do is create a class that implements IHttpHandler, implements a ProcessRequest method, and implements an IsReusable property. Using VS 2005 makes all of this trivially easy. The template in VS also adds an @ WebHandler directive at the top of the file, which looks a lot like an @ Page directive.
Do all this and make sure the file has an .ashx extension, and you can put the file anywhere. When ASP.NET sees the .ashx extension, it knows what to do.
But ASP.NET does not, of course, know what to do with an .rss extension. What I did was:
Ok, let's hold up right here.
- In IIS, I mapped the .rss extension to the C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll ISAPI. This tells IIS to hand the .rss requests to ASP.NET.
- In ASP.NET, I edited the Web.config file and added a mapping for the handler:
<httpHandlers>This tells ASP.NET that when it sees a request for blogcommentsfeed.rss, invoke the BlogCommentsFeed class.
<add verb="GET" path="blogcommentsfeed.rss" type="BlogCommentsFeed" />
- I renamed BlogCommentsFeed.ashx to BlogCommentsFeed.rss.
Test your chops. Did this work? Answer: no. Error: can't find
But of course: there is no such class! I never compiled any such class and put it in Bin. A reminder, let's call it, about how ASP.NET not only knows how to handle handlers named with .ashx, but it knows to compile them.
I copied BlogCommentsFeed.rss to App_Code. Did it work? Uh ... no. ASP.NET compiles class files in that folder, as long as it knows what the heck they are. But this mysterious .rss extension, says ASP.NET, I know nothing about that. Rename .rss extension to .vb, sheepishly.
I assume you had all this sussed out.
After I moved the file to the App_Code folder and renamed it to .vb, did it work? Mmmm, no. Why not? Compiler barfed on the @ WebHandler directive. The directive is useful for when ASP.NET is going to throw a parser at the file, but for plain jane class files (as in the App_Code folder), it's illegal.
After I removed the @ WebHandler directive, did it work? Well, no. I was getting 404-ish errors. Hmm, hmm. Aha! The request is for mikepope.com/blog/BlogCommentsFeed.rss. but there's no such file, right? Just BlogCommentsFeed.vb, which is (will be, should be) invoked in response to requests for the now non-existent BlogCommentsFeed.rss file.
And here I surprised myself by remembering the fix for this. Over in IIS, you can tell it not to look for a physical file, and just let the ISAPI handle things, thank you:
And then, finally, all was fixed, as you can see.
I must put in a good word here for ... shhh ... our docs, which walked me through this. (Well, most of it.) The whole bidness is described right here: How to: Create Synchronous HTTP Handlers. Yay for us.