为一项禁用 Sitecore 的 Html 缓存

发布于 2024-11-14 12:20:29 字数 3399 浏览 2 评论 0原文

我想禁用 1 个项目的 html 缓存,以便始终呈现它。

背景:

我需要显示存储在单独数据库中的公司信息。在 sitecore 中,我有 1 个项目,其中包含显示所需信息的用户控件,并根据上下文参数确定要显示哪家公司。

sitecore 树如下所示:

/sitecore
  /content
    /home
      /company-information

url 为:/show-company-information/[company-name]-[company-id]。我有一个管道模块,用于解析 url 并将公司信息设置为当前项目,并将公司 id 添加到 HttpContext.Current.Items 中。这就是我的用户控件确定要呈现哪些公司信息的方式。

它在开发中一切正常,但一旦将其部署到内容交付服务器,它就会停止正常工作。第一次访问该页面时,它会被缓存,并且每个连续请求都会返回第一次缓存的公司信息。

我当前的解决方法是在解析公司信息的同一管道步骤中清除公司信息项的 HTML 缓存,但这似乎是一个非常肮脏的解决方案。

有没有更好的方法来达到相同的结果?


编辑

以下是网站在 web.config 中的设置方式以及 Web 数据库配置:

<site name="website" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content/Home/" startItem="/home" language="en-GB" database="web" domain="extranet" loginPage="/user-login.aspx" allowDebug="true" cacheHtml="true" htmlCacheSize="400MB" registryCacheSize="500KB" viewStateCacheSize="500KB" xslCacheSize="20MB" filteredItemsCacheSize="20MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" />

<!-- CACHE SIZES -->
    <cacheSizes>
      <sites>
        <website>
          <html>500MB</html>
          <registry>500KB</registry>
          <viewState>500KB</viewState>
          <xsl>200MB</xsl>
        </website>
      </sites>
    </cacheSizes>

<database id="web" singleInstance="true" type="Sitecore.Data.Database, Sitecore.Kernel">
    <param desc="name">$(id)</param>
    <icon>Network/16x16/earth.png</icon>
    <securityEnabled>true</securityEnabled>
    <dataProviders hint="list:AddDataProvider">
      <dataProvider ref="dataProviders/main" param1="$(id)">
        <disableGroup>publishing</disableGroup>
        <prefetch hint="raw:AddPrefetch">
          <sc.include file="/App_Config/Prefetch/Common.config" />
          <sc.include file="/App_Config/Prefetch/Web.config" />
        </prefetch>
      </dataProvider>
    </dataProviders>
    <indexes hint="list:AddIndex">
      <index path="indexes/index[@id='articleIndex']" />
    </indexes>
    <proxiesEnabled>false</proxiesEnabled>
    <proxyDataProvider ref="proxyDataProviders/main" param1="$(id)" />
    <archives hint="raw:AddArchive">
      <archive name="archive" />
      <archive name="recyclebin" />
    </archives>
    <Engines.HistoryEngine.Storage>
      <obj type="Sitecore.Data.$(database).$(database)HistoryStorage, Sitecore.Kernel">
        <param connectionStringName="$(id)" />
        <EntryLifeTime>30.00:00:00</EntryLifeTime>
      </obj>
    </Engines.HistoryEngine.Storage>
    <cacheSizes hint="setting">
      <data>400MB</data>
      <items>400MB</items>
      <paths>10MB</paths>
      <standardValues>1MB</standardValues>
    </cacheSizes>
  </database>
</databases>

页面布局结构:

layout - no output caching
  - sublayout - no caching options ticked
    - offending sublayout - no caching options ticked

我们是否做错了什么,导致如此积极地缓存?

I want to disable the html cache for 1 item so it is always rendered.

Background:

I need to show information for companies stored in a separate database. In sitecore I have 1 item which has the user control that shows the required information and depending on a Context parameter I figure out which company to show.

The sitecore tree look like this:

/sitecore
  /content
    /home
      /company-information

The url is: /show-company-information/[company-name]-[company-id]. I have a pipeline module that parses the url and sets the company information as the current item and adds the company id to HttpContext.Current.Items. That's how my user control figures out which company information to render.

It all works fine in development but once you deploy it to a Content Delivery server it stops working correctly. The first time the page is accessed it gets cached and every consecutive request returns the company information that was cached the first time.

My current workaround is to clear the HTML cache for the company-info item in the same pipeline step that parses the company-information but it seems a really dirty solution.

Is there a better way to achieve the same result?


EDIT

Here is how the site is setup in web.config and also the web database configuration:

<site name="website" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content/Home/" startItem="/home" language="en-GB" database="web" domain="extranet" loginPage="/user-login.aspx" allowDebug="true" cacheHtml="true" htmlCacheSize="400MB" registryCacheSize="500KB" viewStateCacheSize="500KB" xslCacheSize="20MB" filteredItemsCacheSize="20MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" />

<!-- CACHE SIZES -->
    <cacheSizes>
      <sites>
        <website>
          <html>500MB</html>
          <registry>500KB</registry>
          <viewState>500KB</viewState>
          <xsl>200MB</xsl>
        </website>
      </sites>
    </cacheSizes>

<database id="web" singleInstance="true" type="Sitecore.Data.Database, Sitecore.Kernel">
    <param desc="name">$(id)</param>
    <icon>Network/16x16/earth.png</icon>
    <securityEnabled>true</securityEnabled>
    <dataProviders hint="list:AddDataProvider">
      <dataProvider ref="dataProviders/main" param1="$(id)">
        <disableGroup>publishing</disableGroup>
        <prefetch hint="raw:AddPrefetch">
          <sc.include file="/App_Config/Prefetch/Common.config" />
          <sc.include file="/App_Config/Prefetch/Web.config" />
        </prefetch>
      </dataProvider>
    </dataProviders>
    <indexes hint="list:AddIndex">
      <index path="indexes/index[@id='articleIndex']" />
    </indexes>
    <proxiesEnabled>false</proxiesEnabled>
    <proxyDataProvider ref="proxyDataProviders/main" param1="$(id)" />
    <archives hint="raw:AddArchive">
      <archive name="archive" />
      <archive name="recyclebin" />
    </archives>
    <Engines.HistoryEngine.Storage>
      <obj type="Sitecore.Data.$(database).$(database)HistoryStorage, Sitecore.Kernel">
        <param connectionStringName="$(id)" />
        <EntryLifeTime>30.00:00:00</EntryLifeTime>
      </obj>
    </Engines.HistoryEngine.Storage>
    <cacheSizes hint="setting">
      <data>400MB</data>
      <items>400MB</items>
      <paths>10MB</paths>
      <standardValues>1MB</standardValues>
    </cacheSizes>
  </database>
</databases>

Page layouts structure:

layout - no output caching
  - sublayout - no caching options ticked
    - offending sublayout - no caching options ticked

Are we doing anything wrong for this to be cached so aggressively?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

荆棘i 2024-11-21 12:20:29

您可以使用 CacheManager 在页面加载事件期间关闭缓存,然后在 PreRender 中将其重新打开。这将确保页面的 html/xslt 控件不被缓存。

CacheManager 类具有所有控件在检索 HTML 缓存时使用的以下方法

/// <summary>
/// Gets the HTML cache.
/// </summary>
/// <param name="site">The site.</param>
/// <returns>The HTML cache.</returns>
public static HtmlCache GetHtmlCache(SiteContext site)
{
  if (_enabled && (site != null))
  {
    return site.Caches.HtmlCache;
  }
  return null;
}

,因此将 Enabled 属性设置为 false 将停止从缓存中呈现控件:

CacheManager.Enabled = false;

虽然很残酷,但确实有效。

You can use the CacheManager to turn off caching during the Page Load event then turn it back on in PreRender. This will ensure that the page's html / xslt controls are not cached.

The CacheManager Class has the following method used by all controls when retrieving HTML caches

/// <summary>
/// Gets the HTML cache.
/// </summary>
/// <param name="site">The site.</param>
/// <returns>The HTML cache.</returns>
public static HtmlCache GetHtmlCache(SiteContext site)
{
  if (_enabled && (site != null))
  {
    return site.Caches.HtmlCache;
  }
  return null;
}

So setting the Enabled Property to false will stop the controls being rendered from the cache:

CacheManager.Enabled = false;

Its brutal but it works.

靑春怀旧 2024-11-21 12:20:29

如果您的 HTML 被缓存,则它来自特定的渲染,例如特定的子布局。如果您将子布局设置为缓存并因“布局详细信息”中的任何内容而有所不同,请撤消该操作。或者,您可能在代码中执行此操作,在这种情况下,您可以更改 C# 以不缓存它。

这是设置为缓存的代码中的子布局,您可能不想缓存类似的内容:

<sc:Sublayout Path="~/layouts/sublayouts/mycontrol.ascx" Cacheable="true" runat="server" />

If your HTML is being cached, its from a specific rendering, e.g. a specific sublayout. If you have a sublayout set to cache and vary by anything in Layout Details, undo that. Or, you may be doing it in code, in which case you can change your C# to not cache it.

Here's a sublayout in code that is set to cache, you may have something like this that you'd want to not cache:

<sc:Sublayout Path="~/layouts/sublayouts/mycontrol.ascx" Cacheable="true" runat="server" />
狼性发作 2024-11-21 12:20:29

如果仅通过发布任何 sitecore 项目即可解决此缓存问题,则可以安全地假设其为 sitecore HTML 缓存。

任何启用缓存的布局或子布局也将缓存其中添加的任何控件的输出。因此,如果此控件或渲染的任何父子布局启用了缓存,则您需要禁用它。

查看页面缓存设置的一种简单方法是通过调试器 [开始] > [调试]
将鼠标悬停在控件上将允许您查看其结果缓存设置。

If this cache problem is cleared by just publishing any sitecore item, then its safe to assume its the sitecore HTML cache.

Any layout or sublayout with caching enabled will also cache the output any control added within it. So if any parent sublayout of this control or rendering has caching enabled you'll need to disable it.

An easy way to view the cache settings for your page is via the debugger [Start] > [Debug]
Hovering over the controls will allow you to view their resultant cache settings.

往事风中埋 2024-11-21 12:20:29

如果您的项目是子布局,则可以在页面编辑器组件属性中或通过“缓存”部分中的子布局项目的定义来禁用其渲染缓存。

例如,我有一个禁用缓存的搜索结果子布局。

If your item is a sublayout, you can disable its rendering cache in the page editor component properties or through the definition of the sublayout item in the Cache section.

For example, I have a search results sublayout with cache disabled.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文