C# ASP.NET MVC 3自定义路由基础和输出缓存

C# ASP.NET MVC 3自定义路由基础和输出缓存,c#,asp.net-mvc,asp.net-mvc-routing,outputcache,C#,Asp.net Mvc,Asp.net Mvc Routing,Outputcache,我的自定义RouteBase实现和[OutputCache]有问题。 我们有一个CMS,其中URL映射到某些内容页。每种类型的内容页都由不同的控制器(和不同的视图)处理。URL是完全免费的,我们需要不同的控制器,因此“catchall”路由不可用。因此,我们构建了一个自定义RouteBase实现,它调用数据库来查找所有URL。数据库知道要使用哪个控制器和操作(基于内容页类型) 这真是太好了 但是,将其与[OutputCache]属性相结合,输出缓存不起作用(页面仍然有效)。我们确保[Output

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

这真是太好了

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

调试outputcaching非常困难,属性就在那里,我们使用它,它不工作。。。如何处理这个问题的想法将是非常受欢迎的,正确的答案也是如此

控制器如下所示:

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();
  }
}
自定义路由如下所示:

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();
  }
}
公共类CmsPageRoute:RouteBase
{
专用IRouteService(路由服务);;
专用字典_urlsToRouteData;
公共CmsPageRoute(IRouteService路由服务)
{
这._routeService=routeService;
这个.SetCmsRoutes();
}
public void SetCmsRoutes()
{
var urlsToRouteData=新字典();
foreach(此中的var route.\u routeService.GetRoutes())//从数据库获取CMS页面的路由数据
{
添加(route.Url,PrepareRouteData(route));
}
联锁交换(参考urlsToRouteData,urlsToRouteData);
}
公共覆盖路由数据GetRoutedData(System.Web.HttpContextBase httpContext)
{
RouteData RouteData;
if(_urlsToRouteData.TryGetValue(httpContext.Request.Path,out routedData))
返回路由数据;
其他的
返回null;
}
公共覆盖VirtualPathData GetVirtualPath(RequestContext RequestContext,RouteValueDictionary值)
{
返回null;
}
专用路由数据PrepareRouteData(ContentRouteData contentRoute)
{
var routeData=new routeData(这是新的MvcRouteHandler());
添加(“控制器”,contentRoute.controller);
routeData.Values.Add(“action”,contentRoute.action);
RoutedData.Values.Add(“区域”,contentRoute.area);
RoutedData.Values.Add(“pageid”,contentRoute.Constraints[“pageid”]);//用于在控制器方法中标识页面id的变量
添加(“名称空间”,新[]{contentRoute.Namespace});
添加(“区域”,contentRoute.area);
返回路由数据;
}
//路由会定期更新
public void UpdateRoutes()
{
SetCmsRoutes();
}
}

谢谢你一直读到最后

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

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

您可以在此处查看以自定义缓存:


另外,请检查缓存位置。

最后,我们跟踪到一个调用

 ... data-role="@this.FirstVisit" ...
在我们的
\u Layout.cshtml

这调用了自定义视图页面上的一个属性,该属性又调用了一个始终设置cookie的服务。(Yikes在服务中设置cookies!,我们知道!)

如果不是周五,在冲刺结束时,我们可能会注意到缓存被破坏
缓存控制:no Cache=“Set Cookie”:
Http头


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

顺便说一句,我忘了提到我查看了性能计数器“ASP.NET应用程序/输出缓存项”,当我成功地将页面添加到缓存时,它会被触发,但是,当使用我的自定义RouteBase实现调用上述控制器时,情况就不一样了。在周末,我将其背后的逻辑提取到了最小的示例中,它工作了。然而,在我们更大的项目中,情况并非如此。所以我应该努力去理解为什么它不起作用。调试输出缓存不够简单:(您试图缓存到哪里?您希望IIS缓存您的页面还是希望客户端(浏览器)缓存?在IIS中缓存可能很困难,因为IIS可能使用简单的URL形式,但通过设置响应,在客户端计算机中缓存很容易。Expires我会查看它,并尽快为您提供解决方案。您可以更具体地说明“
OutputCache
不起作用”的含义。谢谢,我发现了这些问题。VaryByParam=“*”是MVC3中的默认值