开发者

No trailing slash in hostname, HttpResponse.RemoveOutputCacheItem doesn't work

I'm in a bit of a pickle here.

I have an action for which the output is fairly static, until another action is used to update the datasource for the first action. I use HttpResponse.RemoveOutputCacheItem to remove that action's cached output so that it is refreshed next time the user loads it.

Basically I have an action like this:

[OutputCache(Duration=86400, Location=OutputCacheLocation.Server)]
public ActionResult In开发者_运维百科dex()
{
    return ...
}

on my HomeController, and another action on another controller that updates the information used in the former:

public ActionResult SaveMenu(int id, Menu menu)
{
    ...
    HttpResponse.RemoveOutputCacheItem(Url.Action("Index", "Home"));
    ...
}

The crazy thing is that this works, as long as you're either loading the URLs http://site/ or http://site/Home/Index. When you use the URL http://site it never refreshes.

Why is that?


It has to do with the way the OutputCacheAttribute works, specifically on its dependency on RouteData not being null. The relevant part is:

public override void OnResultExecuting(ResultExecutingContext filterContext)
{
    if (filterContext == null)
    {
        throw new ArgumentNullException("filterContext");
    }
    if (!filterContext.IsChildAction)
    {
        new OutputCachedPage(this._cacheSettings).ProcessRequest(HttpContext.Current);
    }
 }

The ResultExecutingContext filterContext derives from ControllerContext. This is the source for ControllerContext.IsChildAction:

public virtual bool IsChildAction
{
    get
    {
        RouteData routeData = this.RouteData;
        if (routeData == null)
        {
            return false;
        }
        return routeData.DataTokens.ContainsKey("ParentActionViewContext");
    }
}

So, why is this relevant to your question?

Because when you omit the "/" then your Route does not match anything. The default route is "/". An article that explains this more in depth is here: http://www.58bits.com/blog/2008/09/29/ASPNet-MVC-And-Routing-Defaultaspx.aspx . It was written to explain why the Default.aspx file was necessary in ASP.NET MVC 1 projects, but the reason is rooted in the same place.

So, basically, the RouteData is null, so the OutputCacheAttribute can't work. You can solve your problem by doing what Michael Jasper suggested and leveraging URL Rewriting.


IIS has a very usefull module called URL Rewrite. One of the options is to remove or append a trailing slash to all/specific urls. If it is simply the trailing slash that is the problem, this should work.


I've seen a similar behavior in the way SharePoint behaves. SharePoint became confused with http://site; it was unable to determine if the URL was to a File or a SharePoint Site. There's probably something similar going on here.

You've probably resolved the problem by appending the URL with a trailing slash; but, just in case you haven't:

url = string.Format( "{0}/", url.TrimEnd( '/' ) );
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜