简体   繁体   English

ASP.NET MVC 3自定义RouteBase和OutputCache

[英]ASP.NET MVC 3 Custom RouteBase and OutputCache

I have a problem with my custom RouteBase implementation and [OutputCache] . 我的自定义RouteBase实现和[OutputCache] We have a CMS in which urls are mapped to certain content pages. 我们有一个CMS,其中URL被映射到某些内容页面。 Each type of content page is handled by a different controller (and different views). 每种类型的内容页面由不同的控制器(和不同的视图)处理。 The urls are completely free and we want different controllers, so a "catchall" route is not usable. 网址是完全免费的,我们需要不同的控制器,因此“catchall”路由不可用。 So we build a custom RouteBase implementation that calls the database to find all the urls. 因此,我们构建了一个自定义RouteBase实现,该实现调用数据库来查找所有URL。 The database knows which Controller and Action to use (based on the content page type). 数据库知道要使用哪个Controller和Action(基于内容页面类型)。

This works just great. 这很有用。

However, combining this with the [OutputCache] attribute, output caching doesn't work (the page still works). 但是,将此与[OutputCache]属性相结合,输出缓存不起作用(页面仍然有效)。 We made sure [OutputCache] works on our "normal" routes. 我们确保[OutputCache]适用于我们的“普通”路由。

It is very difficult to debug outputcaching, the attribute is there we us it, it doesn't work... Ideas how to approach this would be very welcome, as would the right answer! 调试输出缓存是非常困难的,属性就在那里我们使用它,它不起作用...想法如何处理这将是非常受欢迎的,正确的答案也是如此!

The controller looks like this: 控制器看起来像这样:

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);
  }
}

The custom route looks like this: 自定义路线如下所示:

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();
  }
}

Thank you for reading until the end! 谢谢你的阅读直到最后!

In the end we tracked it down to a call to 最后我们跟踪了它的电话

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

in our _Layout.cshtml 在我们的_Layout.cshtml

This called a property on our custom view page that in turn called a service which always set a cookie. 这在我们的自定义视图页面上调用了一个属性,该属性又调用了一个始终设置cookie的服务。 ( Yikes setting cookies in services! , we know!) Yikes在服务中设置cookie!,我们知道!)

Had it not been Friday and at the end of the sprint we might have noticed the cache busting Cache-Control: no-cache="Set-Cookie": Http Header. 如果不是星期五和冲刺结束时我们可能已经注意到缓存破坏Cache-Control: no-cache="Set-Cookie": Http Header。

I still don't understand why this only busted the cache for our custom RouteBase implementation and not all pages. 我仍然不明白为什么这只会破坏我们自定义RouteBase实现的缓存而不是所有页面。 All pages use the same _Layout.cshtml . 所有页面都使用相同的_Layout.cshtml

You can try the following code if it helps 如果有帮助,您可以尝试以下代码

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

You might look here to customize caching : 您可以在这里查看自定义缓存:

Also, check the cache location. 另外,检查缓存位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM