Currently I am working on an upgrade to Sitecore 8.2 Update 1 from Sitecore 8.1 Initial Release, and after running the upgrade wizard, the upgrade failed. The fail was so catastrophic, I was not even able to view showconfig.aspx, leaving me to resort to looking in the Event Log, and to find this wonderful message
Event code: 3005 Event message: An unhandled exception has occurred. Event time: 22/12/2016 15:38:53 Event time (UTC): 22/12/2016 15:38:53 Event ID: 85882dee8c56406d85edec3b3d6d116f Event sequence: 8 Event occurrence: 1 Event detail code: 0 Application information: Application domain: /LM/W3SVC/2/ROOT-16-131268946928384207 Trust level: Full Application Virtual Path: / Application Path: D:\Projects\src\web\Project.Corporate.Web\ Machine name: DARRENGUY Process information: Process ID: 32152 Process name: w3wp.exe Account name: DOMAIN\darrenguy Exception information: Exception type: MissingMethodException Exception message: Method not found: 'Boolean PageMode.get_IsPageEditorEditing()'. at Project.Lib.Sitecore.Pipeline.UrlRedirects.PageLevelRedirect.Process(HttpRequestArgs args) at (Object , Object[] ) at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args) at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain) at Sitecore.Nexus.Web.HttpModule.(Object , EventArgs ) at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) Request information: Request URL: http://project.local/sitecore/admin/Wizard/InstallUpdatePackage.aspx?poststep=1&prefix=WizardPage&page=4&originalurl=/sitecore/admin/UpdateInstallationWizard.aspx&header=lblHeader&a=1&pm=7&m=0&ceq=1&ch=1&pn=Upgrade from 8.1 rev. 151003 to 8.2 rev. 161115&ihf=Upgrade_20161222T153157850 Request path: /sitecore/admin/Wizard/InstallUpdatePackage.aspx User host address: 127.0.0.1 User: Is authenticated: False Authentication Type: Thread account name: DOMAIN\darrenguy Thread information: Thread ID: 270 Thread account name: DOMAIN\darrenguy Is impersonating: False Stack trace: at Project.Lib.Sitecore.Pipeline.UrlRedirects.PageLevelRedirect.Process(HttpRequestArgs args) at (Object , Object[] ) at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args) at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain) at Sitecore.Nexus.Web.HttpModule.(Object , EventArgs ) at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) Custom event details:
My first thought was that the error was in a custom pipeline, so I would comment out the pipeline in my config file, and try the upgrade again. This time the upgrade failed in a different pipeline. Disabled the next pipeline, and tried the upgrade again. This time the upgrade was successful, but neither Sitecore, nor the site would load. It was at this point I knew I was going to have to investigate this further.
The first version of Sitecore I used was 6.5. As of the time this was written, the latest version is Sitecore 8.2. So without thinking about it, I have been using
Sitecore.Context.PageMode.IsPageEditor
or
Sitecore.Context.PageMode.IsPageEditorEditing
within my code or views, and too show how long in the tooth, previously in my ascx files.
Sitecore depreciated the variables IsPageEditor, and IsPageEditorEditing in Sitecore 8.0 Update 6
The properties IsPageEditor, IsPageEditorDesigning and IsPageEditorEditing in the class Context.PageMode from Sitecore namespace have been deprecated in favor of the new introduced properties IsExperienceEditor and IsExperienceEditorEditing. Old properties will be removed in one of the future major versions. (438475)
This was the only mention I could find about this.
In Sitecore 8.1 Initial Release, the version I was currently upgrading from, the methods do not have the Obsolete flag, which would have helped.
This is the decompiled code from Sitecore.Kernal
/// <summary> /// Gets a value indicating whether this instance is page editor. /// </summary> /// <value> /// <c>true</c> if this instance is page editor; otherwise, false. /// </value> public static bool IsPageEditor { get { return Context.Site.DisplayMode == DisplayMode.Edit; } } /// <summary> /// Gets a value indicating whether this instance is page editor editing. /// </summary> /// <value> /// <c>true</c> if this instance is page editor editing; otherwise, false. /// </value> public static bool IsPageEditorEditing { get { SiteContext site = Context.Site; if (site == null || WebUtil.GetCookieBool(site.GetCookieKey("sc_navigate"), false) || (!Context.PageMode.IsPageEditor || !(WebUtil.GetQueryString("sc_ce") != "1"))) return false; return WebUtil.GetQueryString("sc_webedit") != "0"; } }
Only three methods where marked with an Obsolete attribute:
- IsPageEditorClassic with Obsolete message “Deprecated”
- IsPageEditorDesigning with Obsolete message “Use IsPageEditorEditing instead”
- IsPageEditorNavigating with Obsolete message “The method is deprecated”
Sitecore may have added the Obsolete attribute onto the methods in Sitecore 8.1 Update 1 or later, but I did not check sitecore.kernal.dll in all those versions.
I could have gone down the route of using compiler variables, but the problem is that they are compiler variables, they wont solve the different variable names to be used between Sitecore 8.1 and 8.2. In addition I would still have my upgrade problems as I would be back with the a failing upgrade process as the code would still be trying to access the methods that are no longer present.
Therefore I decided to create a proxy class for PageMode that will use reflection to determine if method IsPageEditor or IsExperienceEditor is available, enabling the code to work with Sitecore 8.1 or 8.2
using Sitecore; namespace Project.Lib.Sitecore { public static class PageModeProxy { public static bool IsPageEditor => IsExperienceEditor; public static bool IsPageEditorEditing => IsExperienceEditorEditing; public static bool IsExperienceEditor => GetPropertyValue(DoesPropertyExist("IsExperienceEditor") ? "IsExperienceEditor" : "IsPageEditor"); public static bool IsExperienceEditorEditing => GetPropertyValue(DoesPropertyExist("IsExperienceEditorEditing") ? "IsExperienceEditorEditing" : "IsPageEditorEditing"); private static bool DoesPropertyExist(string propertyName) { return (typeof(Context.PageMode).GetProperty(propertyName) != null); } private static bool GetPropertyValue(string propertyName) { var prop = typeof(Context.PageMode).GetProperty(propertyName); return (bool)(prop.GetValue(typeof(Context.PageMode), null)); } } }
A quick search for Sitecore.Context.PageMode and replace with PageModeProxy, and my solution is ready. Now I have no problems upgrading my solution to Sitecore 8.2
As noted above, this class does use reflections but as this is just a workaround just so that I could successfully complete the upgrade to Sitecore 8.2. Once the upgrade to Sitecore 8.2 completed successfully, I updated the proxy class to remove the reflection, so any potential speed problems will be removed.
Leave a Reply