views:

313

answers:

1

I have the following action:

public class HomeController : Controller
{
    public ActionResult Index(int? id) { /* ... */ }
}

I'd like to [OutputCache] that action, but I'd like that either:

  • it doesn't use the cache if id == null; or
  • it uses the cache if id == null but with a different duration.

I think I can achieve this by:

public class HomeController : Controller
{
    [OutputCache(VaryByParam = "none", Duration = 3600)]
    public ActionResult Index() { /* ... */ }

    [OutputCache(VaryByParam = "id", Duration = 60)]
    public ActionResult Index(int id) { /* ... */ }
}

However this solution implies 2 actions, when the id is actually optional, so this might create some code repetition. Of course I could do something like

public class HomeController : Controller
{
    [OutputCache(VaryByParam = "none", Duration = 3600)]
    public ActionResult Index() { return IndexHelper(null); }

    [OutputCache(VaryByParam = "id", Duration = 60)]
    public ActionResult Index(int id) { return IndexHelper(id); }

    private ActionResult IndexHelper(int? id) { /* ... */ }
}

but this seems ugly.

How would you implement this?

+2  A: 

I think what you have is probably the cleanest option.

Another option, which I haven't tested, may be to set the VaryByCustom parameter and override GetVaryByCustomString in Global.asax.

public override string GetVaryByCustomString(HttpContext context, string arg)
{
    if (arg.ToLower() == “id”)
    {
        // Extract and return value of id from query string, if present.
    }

    return base.GetVaryByCustomString(context, arg);
}

See here for more information: http://codebetter.com/blogs/darrell.norton/archive/2004/05/04/12724.aspx

Richard Poole