While doing a major update from CMS 4.62 to CMS 6 R2 I have encountered several of issues, the rest of the interesting challenges you can read about in these posts:
- Shortcut and external link property in EPiServer
- Upgrade an EPiServer CMS 4.61 to 6 is not without bumps
Other important posts to read before this, since it is highly relevant. is the post by Ted about his experiences of doing a similar upgrade. This is particularly interesting if you are running ETF on the site that you are trying to upgrade. In short the the scripts of TinyMCE was not loaded correctly.
What was the issue?
I had completed the upgrade and from a visitors point of view everything seemed to be working. I logged in as an editor and started to browse through pages to check all properties. My first glance made me thing that everything seemed to be okay, but after a closer look I saw that there was no editor for relevant properties.
For example the MainBody, looked like this:
As you can see this has loaded the legacy control, which is actually a control without editor functionality. What I wanted was the new TinyMCE control. From experience and together with my colleague Thomas we started to check the settings.
So we switched to admin-mode and started to look at the standard page to get some clues. We found that the standard page was configured to use this for the MainBody property:
This actually means that the LegacyControl will e run or the “EPiSErver CMS 5 editor”. You could switch the control here to the TinyMCE, but first how do you force the whole site to use the TinyMCE control?
Specific settings of the editors in EPiServer
It is also possible to configure specific settings on both the old control and the the new TinyMCE control. While in the admin-mode go to:
Then scroll down to the XHTML-property:
Now you should be able to see these settings:
Now onto how to remove the legacy control.
How to remove the Legacy Control of XHtml properties in EPiServer
Start with the web.config and look for a tag called: episerver.baseLibrary.
This tag normally contains two classFactories. One of which is to control the Legacy control for the editor.
1: <add type="EPiServer.Core.PropertyControlClassFactory, EPiServer" id="PropertyControlFactory">
2: <register type="EPiServer.SpecializedProperties.PropertyXhtmlString, EPiServer" mappedType="EPiServer.Web.PropertyControls.LegacyPropertyXhtmlStringControl, EPiServer" />
3: <register type="EPiServer.Core.PropertyLongString, EPiServer" mappedType="EPiServer.Web.PropertyControls.LegacyPropertyXhtmlStringControl, EPiServer" />
4: </add>
If you want to get rid of this option of using the legacy, just remove the two <register> tags and you are set to go.
1: <add type="EPiServer.Core.PropertyControlClassFactory, EPiServer" id="PropertyControlFactory"></add>
Once this is done, restart the site and browse to the page where you know a xhtml-property exists. When I did this we got an LoaderException all over the screen, see below.
LoaderException – System.Reflection.ReflectionTypeLoadException
1: Server Error in '/' Application.
2: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
3: Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
4:
5: Exception Details: System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
6:
7: Source Error:
8:
9: An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
10:
11: Stack Trace:
12:
13: [ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.]
14: System.Reflection.RuntimeModule.GetTypes(RuntimeModule module) +0
15: System.Reflection.Assembly.GetTypes() +159
16: EPiServer.Data.Dynamic.TypeResolver.ResolveType(Object sender, ResolveEventArgs args) +99
17: System.AppDomain.OnTypeResolveEvent(RuntimeAssembly assembly, String typeName) +12514283
18: System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, Boolean loadTypeFromPartialName, ObjectHandleOnStack type) +0
19: System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, Boolean loadTypeFromPartialName) +314
20: System.Type.GetType(String typeName, Boolean throwOnError) +89
21: EPiServer.Core.PropertySettings.PropertySettingsContainer.get_PropertyControl() +67
22: EPiServer.Core.PropertyControlClassFactory.CreatePropertyControl(PropertyData propertyData) +55
23: EPiServer.Web.WebControls.Property.CreateChildControls() +337
24: System.Web.UI.Control.EnsureChildControls() +182
25: System.Web.UI.Control.PreRenderRecursiveInternal() +60
26: System.Web.UI.Control.PreRenderRecursiveInternal() +222
27: System.Web.UI.Control.PreRenderRecursiveInternal() +222
28: System.Web.UI.Control.PreRenderRecursiveInternal() +222
29: System.Web.UI.Control.PreRenderRecursiveInternal() +222
30: System.Web.UI.Control.PreRenderRecursiveInternal() +222
31: System.Web.UI.Control.PreRenderRecursiveInternal() +222
32: System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +4201
33:
34:
35: Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.237
This could be caused by many things, but what caught our attention was these three rows:
System.Reflection.RuntimeModule.GetTypes(RuntimeModule module) +0
EPiServer.Data.Dynamic.TypeResolver.ResolveType(Object sender, ResolveEventArgs args) +99
EPiServer.Core.PropertySettings.PropertySettingsContainer.get_PropertyControl() +67
A small note about this: If you get this and you have downloaded files from the Internet, they might be blocked. Then you normally get the Unable to load one or more of the requested types. This can be done by right-clicking on the file, selecting “Advanced” on the General tab. If this is the case select “Unblock”.
Another issue that can cause this is if you have gotten a .zip file from a Mac-machine, then make sure you check that the file is not “encrypted”. It should show up as green in Windows Explorer. Just follow the same procedure as above to unencrypt.
We got the feeling that this have to be related to settings or the loaded system-files. So we proceded our hunt for what was causing this error.
- First we made sure that the loaded EPiServer files were correct and of the right version.
- Made sure that the assembly bindings matched the loaded files (can be found in web.config)
- Made sure that if the site is supposed to run on .Net 4 that the settings matched this. Can be found under the node system.codedom in web.config. Look for the value CompilerVersion.
1: <system.codedom>
2: <compilers>
3: <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider,System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4">
4: <providerOption name="CompilerVersion" value="v4.0" />
5: <providerOption name="WarnAsError" value="false" />
6: </compiler>
7: </compilers>
8: </system.codedom>
None of this seemed to give any result for us. Although all of these settings are good to go through, so do them any way!
This was the solution that we found
With some help of JohanO at EPiServer that EPiServers DynamicDataStore contains a TypeResolver that as default tries to resolve types on load. What it does is trying to load “old” types into “new” types (versions). Normally when doing an upgrade you have a legacy of old types, custom properties for example. On upgrade these old properties are put into an assembly called AutogeneratedCustomProperty.dll . This could definitely be one of the factors that is causing this error.
This why one of the rows mentioned above is so interesting or frustrating, you choose: System.Reflection.RuntimeModule.GetTypes(RuntimeModule module) since it is not telling any thing. So to find out what type that is actually causing the error, as Johan suggests, use WinDBG.
Although to get going and get the site up and running again, you can tell the TypeResolver to not run as default. Go back to the web.config and look for the node: <episerver.dataStore>. On the subnode dataStore add the attribute: autoResolveTypes=”false”.
1: <episerver.dataStore>
2: <dataStore autoResolveTypes="false" defaultProvider="EPiServerSQLServerDataStoreProvider">
3: <providers>
4: <add name="EPiServerSQLServerDataStoreProvider" description="SQL Server implementation of Data Store" type="EPiServer.Data.Dynamic.Providers.SqlServerDataStoreProvider, EPiServer.Data" connectionStringName="EPiServerDB" />
5: <add name="EPiServerOracleDataStoreProvider" description="Oracle implementation of Data Store" type="EPiServer.Data.Dynamic.Providers.OracleDataStoreProvider, EPiServer.Data" connectionStringName="EPiServerDB_oracle" />
6: </providers>
7: <cache defaultProvider="httpCacheProvider">
8: <providers>
9: <add name="nullCacheProvider" description="Null Cache implementation of DataStore" type="EPiServer.Data.Cache.NullCacheProvider,EPiServer.Data" />
10: <add name="httpCacheProvider" description="Http Cache implementation of DataStore" type="EPiServer.Data.Cache.HttpRuntimeCacheProvider,EPiServer.Data.Cache" />
11: </providers>
12: </cache>
13: </dataStore>
14: </episerver.dataStore>
After that you are probably good to go.
Thanks Thomas for good teamwork in finding this solution!