Caching of pages on URL path

At the moment we are building up a Epi CMS instance which hosts several sites.
Our content tree is build up in the following way (numbers representing the ID's):

Root (1)
    |_ www.site1.com (2)
        |_ www.site1.com/Contact (3)
        |_ etc.
    |_ www.site2.com (4)
        |_ www.site2.com/Contact (5)
        |_ etc.
    |_ www.site3.com (6)
        |_ www.site3.com/Contact (7)
        |_ etc.
      
Custom Url rewriting (inherited from the FriendlyUrlRewriteProvider) is used to map to the correct branch in the content tree. Our problem is the following:

If, after starting the website, the contact page for site1 is loaded (www.site1.com/Contact), the node with ID 3 is loaded correctly.
If afterwards the contact page for site2 is loaded (www.site2.com/Contact), the node with ID 3 is loaded, which is incorrect. It should be node 5.
After refreshing the page (hitting F5 or Ctrl+F5) on www.site2.com/Contact the proper node/page is loaded (the page with ID 5).

We think the issue has to do with caching of pages in the FriendlyUrlRewriteProvider. We believe the caching is done by using the Path of the URL as the Key. That could explain why both /Contact pages are interfering.
Can someone confirm our suspicion? And if so, can we work around this problem? Is it, for example, possible to change the caching so that the host/domain is included in the caching key?

Thanks in advance!

Jasper


  • Hi,

    Are you overriding TryConvertToInternal?

    Why are you using a custom url rewriter for this? You could set up the pages as real startpages, see http://world.episerver.com/Documentation/Items/Tech-Notes/EPiServer-CMS-6/EPiServer-CMS-60/Enterprise---Configuration/.

  • Thanks for your response!

    The main reason we chose custom url rewriting was that the user has to be able to create new subsites from code. We have created code to generate a new content branch for the site and add the URL to a list which is read by our custom URLRewrite provider.

    Setting pages up as start-pages needs to have nodes added to the EPiServer.config. We thought it was risky to do that in code. Also, the website has to be restarted after adding new website startpage(s) to the config.

  • Ok.

    The (output) cache is varied by parameters, like id and epslanguage, not the path. You can override this in global.asax.

    /// 
    /// Get key to vary cached items by. Overrides EPi's way. Needs values in all settings elements, for example:
    /// httpCacheExpiration="0:1:0"
    /// httpCacheability="Public"
    /// httpCacheVaryByCustom="custom"
    /// httpCacheVaryByParams="needs-a-value-but-not-used"
    /// 
    /// The current request's context.
    /// The string from configuration setting httpCacheVaryByCustom.
    /// The raw URL of the page requested.
    public override string GetVaryByCustomString(HttpContext context, string custom)
    {
        return context.Request.RawUrl;
    }

    Not sure this is the problem though.  You can turn it off by setting httpCacheExpiration to 0:0:0 in episerver.config in the site node.

    The rewritten url in your rewriter is cached too, try debug it and see if the rewritten url is translated to the correct page id.

  • Content is edited

    Yes we tried overriding GetVaryByCustomString, but found it is only called when output caching is enabled. We have output cached disabled in our project.

     

    If i look in the code of the FriendlyURLRewriteProvider:

     

    private bool ResolveUrlAndCache(UrlBuilder url, FriendlyUrlRewriteProvider.LanguageApiMode apiMode, ref object internalObject, out LanguageBranch languageBranch)
    {
        languageBranch = null;
        string text = "EPiServerFriendlyUrl:" + url.Path;
        object obj = CacheManager.Get(text);
        if (obj != null)
        {
            return obj != FriendlyUrlRewriteProvider._noHit && this.UpdateCachedItem(url, obj, ref internalObject, out languageBranch);
        }
        if (this.ConvertToInternalFacade(url, apiMode, ref internalObject, out languageBranch))
        {
            this.AddToCache(url, text, ref internalObject);
            return true;
        }
        this.StoreInCache(text, FriendlyUrlRewriteProvider._noHit);
        return false;
    }

     

    It looks like the object is retrieved from the cache only on the Path of the url. So now i wonder whether the setup of different startnodes will solve the problem.

  • Override the TryConvertToInternal()-method, then you're bypassing the built-in cache. Please see my blog post http://www.dodavinkeln.se/post/2012/03/15/Url-rewriter-for-a-blog.aspx

  • Okay thanks, we will try that. I'll come back to tell whether we were able to fix the problem.

    (sorry you already mentioned overriding TryConvertToInternal in your first reply, but i overread it)

  • We've fixed the problem. Unfortunately we use EPi 6.0 on this project, and that version lacks the TryConvertToInternal()-method. But you pointed us in the right direction.

    We've now overridden the ConvertToInternal method, and reversed-engineered the code from the EPiServer assembly using ILspy. We changed the way the cache key is built up. We changed:

                            string key = "EPiServerFriendlyUrl:" + url.Path;

     To:

                            string key = String.Format("EPiServerFriendlyUrl:{0}{1}", url.Host, url.Path);

     

    It seems to work fine now.

    Thanks for the support.

  • Glad I could help you in the right direction. ConvertToInternal() is the equivalent to TryConvertToInternal() in EPi6.

First   1   Last