I have a problem with my custom RouteBase
implementation and [OutputCache]
. We have a CMS in which urls are mapped to certain content pages. 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. So we build a custom RouteBase implementation that calls the database to find all the urls. The database knows which Controller and Action to use (based on the content page type).
我的自定义RouteBase实现和[OutputCache]有一个问题。我们有一个CMS,其中url映射到某些内容页面。每种类型的内容页面都由不同的控制器(以及不同的视图)处理。url是完全免费的,我们想要不同的控制器,所以“集合”路径不可用。因此我们构建了一个自定义的RouteBase实现,它调用数据库来查找所有的url。数据库知道使用哪个控制器和操作(基于内容页面类型)。
This works just great.
这样做就好了。
However, combining this with the [OutputCache] attribute, output caching doesn't work (the page still works). We made sure [OutputCache] works on our "normal" routes.
但是,将它与[OutputCache]属性组合在一起,输出缓存将不起作用(页面仍然有效)。我们确保[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!
要调试outputcache非常困难,属性是我们自己的,它不起作用……如何处理这个问题的想法将会非常受欢迎,以及正确的答案!
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!
感谢你一直读到最后!
3 个解决方案
#1
1
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. (Yikes setting cookies in services!, we know!)
这调用了自定义视图页面上的一个属性,该属性反过来又调用了一个始终设置cookie的服务。(哎呀,在服务中设置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.
如果不是在周五,在sprint结束的时候,我们可能已经注意到了缓存崩溃的cache - control: no-cache=“Set-Cookie”:Http头。
I still don't understand why this only busted the cache for our custom RouteBase
implementation and not all pages. All pages use the same _Layout.cshtml
.
我仍然不明白为什么这只会破坏我们的自定义RouteBase实现的缓存,而不是所有的页面。所有页面都使用相同的_Layout.cshtml。
#2
0
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);
}
#3
0
You might look here to customize caching :
您可以在这里定制缓存:
- Ignore url values with Outputcache
- 使用Outputcache忽略url值
- Output Cache problem on ViewEngine that use 2 separate view for 1 controller
- 在一个控制器上使用两个独立视图的ViewEngine上的输出缓存问题
Also, check the cache location.
另外,检查缓存位置。
#1
1
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. (Yikes setting cookies in services!, we know!)
这调用了自定义视图页面上的一个属性,该属性反过来又调用了一个始终设置cookie的服务。(哎呀,在服务中设置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.
如果不是在周五,在sprint结束的时候,我们可能已经注意到了缓存崩溃的cache - control: no-cache=“Set-Cookie”:Http头。
I still don't understand why this only busted the cache for our custom RouteBase
implementation and not all pages. All pages use the same _Layout.cshtml
.
我仍然不明白为什么这只会破坏我们的自定义RouteBase实现的缓存,而不是所有的页面。所有页面都使用相同的_Layout.cshtml。
#2
0
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);
}
#3
0
You might look here to customize caching :
您可以在这里定制缓存:
- Ignore url values with Outputcache
- 使用Outputcache忽略url值
- Output Cache problem on ViewEngine that use 2 separate view for 1 controller
- 在一个控制器上使用两个独立视图的ViewEngine上的输出缓存问题
Also, check the cache location.
另外,检查缓存位置。