10

我的自定义RouteBase实现和[OutputCache]. 我们有一个 CMS,其中 url 映射到某些内容页面。每种类型的内容页面由不同的控制器(和不同的视图)处理。url 是完全免费的,我们需要不同的控制器,所以“catchall”路由不可用。因此,我们构建了一个自定义 RouteBase 实现,它调用数据库来查找所有 url。数据库知道要使用哪个控制器和操作(基于内容页面类型)。

这很好用。

但是,将此与 [OutputCache] 属性结合使用,输出缓存不起作用(页面仍然有效)。我们确保 [OutputCache] 在我们的“正常”路线上工作。

调试输出缓存非常困难,属性就在那里,它不起作用......如何解决这个问题的想法非常受欢迎,正确的答案也是如此!

控制器如下所示:

public class TextPageController : BaseController
{
  private readonly ITextPageController textPageController;

  public TextPageController(ITextPageController textPageController)
  {
    this.textPageController = textPageController;
  }

  [OutputCache(Duration = 300)]
  public ActionResult TextPage(string pageid)
  {
    var model = textPageController.GetPage(pageid);
    return View(model);
  }
}

自定义路由如下所示:

public class CmsPageRoute : RouteBase
{
  private IRouteService _routeService;
  private Dictionary<string, RouteData> _urlsToRouteData;

  public CmsPageRoute(IRouteService routeService)
  {
    this._routeService = routeService;
    this.SetCmsRoutes();
  }

  public void SetCmsRoutes()
  {
    var urlsToRouteData = new Dictionary<string, RouteData>();
    foreach (var route in this._routeService.GetRoutes()) // gets RouteData for CMS pages from database
    {
      urlsToRouteData.Add(route.Url, PrepareRouteData(route));
    }
    Interlocked.Exchange(ref _urlsToRouteData, urlsToRouteData);
  }

  public override RouteData GetRouteData(System.Web.HttpContextBase httpContext)
  {
    RouteData routeData;
    if (_urlsToRouteData.TryGetValue(httpContext.Request.Path, out routeData))
      return routeData;
    else
      return null;
  }

  public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
  {
    return null;
  }

  private RouteData PrepareRouteData(ContentRouteData contentRoute)
  {
    var routeData = new RouteData(this, new MvcRouteHandler());

    routeData.Values.Add("controller", contentRoute.Controller);
    routeData.Values.Add("action", contentRoute.Action);
    routeData.Values.Add("area", contentRoute.Area);
    routeData.Values.Add("pageid", contentRoute.Constraints["pageid"]); // variable for identifying page id in controller method

    routeData.DataTokens.Add("Namespaces", new[] { contentRoute.Namespace });
    routeData.DataTokens.Add("area", contentRoute.Area);

    return routeData;
  }

  // routes get periodically updated
  public void UpdateRoutes()
  {
    SetCmsRoutes();
  }
}

感谢您阅读到最后!

4

3 回答 3

1

最后,我们将其追踪到调用

 ... data-role="@this.FirstVisit" ...

在我们的_Layout.cshtml

这在我们的自定义视图页面上调用了一个属性,该属性又调用了一个总是设置 cookie 的服务。(哎呀在服务中设置 cookie!,我们​​知道!)

如果不是星期五,在 sprint 结束时,我们可能已经注意到缓存破坏 Cache-Control: no-cache="Set-Cookie":Http Header。

我仍然不明白为什么这只会破坏我们自定义RouteBase实现的缓存,而不是所有页面。所有页面使用相同的_Layout.cshtml.

于 2012-09-18T14:39:41.497 回答
0

如果有帮助,您可以尝试以下代码

[OutputCache(Duration = 300, VaryByParam="*")] 
public ActionResult TextPage(string pageid) 
{ 
  var model = textPageController.GetPage(pageid); 
  return View(model);
}
于 2012-09-18T13:39:36.333 回答
0

您可能会在这里查看自定义缓存:

另外,检查缓存位置。

于 2012-09-18T14:07:31.597 回答