Another ASP.NET MVC custom ActionResult example

If you’re familiar with ASP.NET MVC this is probably not news to you. If you’re coming from Webforms, you might find this tip helpful.

One of my favorite things about MVC is how easy it is to build custom ActionResults. I previously wrote about building one for returning RSS feeds and this post expands on that idea a little bit.

When I originally set up the ManagedAssembly.com RSS feeds, I added some caching so that the feed would only be generated every 30 minutes resulting in a snapshot of the current set of popular stories. Unfortunately since I hosted the feeds directly, I have very little useful info about how much they’re being used. FeedBurner (when it works) is much better at that so I wanted to switch the feeds over to that but without changing the URLs so I don’t break any existing subscriptions. I had recently read in a post to Twitter by Scott Watermasyk that Graffiti CMS supports FeedBurner by sniffing the user agent and serving the live feed to FeedBurner but at the same URL, redirects real visitors to FeedBurner. This was the perfect solution to my problem, so here’s how I went about implementing it.

First I added a PermanentRedirectResult class that inherits from ActionResult to handle generating the 301 redirect. The built-in RedirectResult uses Response.Redirect which only is capable of issuing a 302 redirect (until ASP.NET 4.0 is out).

public class PermanentRedirectResult : ActionResult
{
    private string _url;
 
    public PermanentRedirectResult(string url) {
        _url = url;
    }
 
    public override void ExecuteResult(ControllerContext context) {
        context.HttpContext.Response.StatusCode = 301;
        context.HttpContext.Response.RedirectLocation = _url;
    }
}

Then in my ControllerBase class that all my controllers inherit from, I added a helper method to simplify calling the result:

public abstract class ControllerBase : Controller
{
    public PermanentRedirectResult PermanentRedirect(string url) {
        return new PermanentRedirectResult(url);
    }
}

Then in the action method I do a simple check for FeedBurner and if it’s not found, issue the redirect. Otherwise return the live feed.

public ActionResult Popular() {
    bool isBot = Request.UserAgent.Contains("FeedBurner");
 
    if (!isBot) {
        return PermanentRedirect(Settings.Feed.PopularFeedUrl);
    }
 
    // *snip* build and return live feed
}

Nice and straightforward and doesn’t break any existing subscriptions. Now with FeedBurner’s stats I can tell exactly how few of you are subscribing to the feed :)

Posted July 14th, 2009 10:43 PM
Read more posts about ASP.NET MVC, Managed Assembly, Tips.

Comments
Link

blog comments powered by Disqus