tirsdag den 29. oktober 2013

Leaving Page Editor mode resulting in a 404 error.

There is a bug in Sitecore, that causes it to generate an excess of cookies when leaving Page Editor mode (clicking the Close button in the ribbon).

This causes browsers to behave weird, and Internet Explorer just displays a 404 error page.

The problem happens, if there is code on the page calling SiteContextFactory.GetSiteContext , which is used to get a SiteContext for a certain site.

For every time this function is called, a new cookies is set, so if you have logic in your solution that uses, you must cache the SiteContext objects you get from GetSiteContext, to work around this problem.

Due to a bug in one of our controls on a solution we where designing, a menu was looking up the SiteContext for every element in a menu, which caused it to fail.

If you want to see the proble, here is a step-by-step guide to how to trigger it - I haven't tested it on anything newer than Sitecore 6.5, but to my knowledge, the bug is still there.

How to trigger:

  1. Create an empty aspx page, and add the following code below to the Page_Load event.
  2. Add this aspx page as a layout in Sitecore, and assign it to an item.
  3. Open the page editor, go to the item, and then click Close on the ribbon.
Here is the code needed to trigger the bug - you would not normally do this, but it trigger the creation of way too many cookies:

            for (int i = 0; i < 300; i++)
            {
                foreach (string siteName in Sitecore.Sites.SiteContextFactory.GetSiteNames())
                {
                    Sitecore.Sites.SiteContextFactory.GetSiteContext(siteName);
                }
            }

Workaround:

Since quite alot of Sitecore's API uses SiteContext objects as parameters, we have to deal with them, which poses these problems when using solutions with multiple sites, that needs to be able to get links across.

However, here is a small code snippet that we are using, that works around this bug:

        internal class SiteContextWrapper : SiteContext
        {
            public SiteContextWrapper(SiteInfo siteInfo) : base(siteInfo, false)
            {
            }
        }

It simply extends the SiteContext class, causing it to be created without setting the cookie.
To get the SiteContext object, you simply class the GetSiteInfo function in SiteContextFactory, and use that to create a new SiteContextWrapper object, which can be cast to a SiteContext object.

Ingen kommentarer:

Send en kommentar