HomeDev GuideRecipesAPI Reference
Dev GuideAPI ReferenceUser GuideLegal TermsGitHubNuGetDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

Upgrade to CMS 7.5

This topic describes breaking changes for Optimizely Content Management System (CMS 7.5) in relation to previous versions, and steps needed to update affected code.

CMS-specific breaking changes

Query parameter “ID” is no longer handled

Previously it was possible to pass in a ID query parameter to control which page that was routed to. This is typically needed to be able to route “classic” links, for example http://sitehost/templates/Page.aspx?id=12. If routing to classic links (like the one in the example) is needed, a special route to handle them needs to be registered. This route can be registered as below:

protected override void RegisterRoutes(System.Web.Routing.RouteCollection routes)
        {
            base.RegisterRoutes(routes);
            routes.Insert(0,ServiceLocator.Current.GetInstance<EPiServer.Web.Routing.ClassicLinkRoute>());
        }

EPiServer.Web.WebControls.SearchDataSource does not support searching for files anymore

The default support for searching for files in the SearchDataSource has been removed. The SearchService in the Alloy MVC template package can be used as a reference implementation to see how file search can be implemented.

MVC EditAttributes should be set on the parent element

If you rendered your images by setting the src attribute to the @Url.ContentUrl(Model.CurrentPage.PageImage) and added the edit attributes to the image tag to make editable in the edit user interface, then you need to change your code to either use PropertyFor or set the EditAttributes on a wrapping element.

<img src="@Url.ContentUrl(Model.CurrentPage.PageImage)" @Html.EditAttributes(x => x.CurrentPage.PageImage)/>

should be changed to

<div @Html.EditAttributes(x => x.CurrentPage.PageImage)>
<img src="@Url.ContentUrl(Model.CurrentPage.PageImage)"/>
</div>

or

@Html.PropertyFor(Model.CurrentPage.PageImage)

Changed behavior of content expiration notification

When content has a stop publish date the behavior of the edit UI has changed. Previously, a warning in the notification field would always be visible if stop publish had been set. This has been changed so that the warning is hidden until the stop publish date is in the near future. How long before the stop publish date the warning becomes visible is controlled by the expirationNotificationPeriod setting in the applicationSettings element in the episerver section of the site configuration files. The default is 60 days. 

ContentProvider capabilities

If the ContentProvider does not support EPiServer.Core.ContentProviderCapabilities.Wastebasket and gets a call on MoveToWastebasket a capability exception will be thrown.
The EPiServer.Configuration.ContentProviderElement.FullSupportString now includes Wastebasket.

Site definitions have moved from config to database

Previously sites where defined in web.config in the sites element under the episerver section as follows:

<episerver>
  <sites>
    <site siteId="somesite">
       <siteSettings pageStartId="4"....
    </site>
  </sites>
  ...
</episerver>

Where siteSettings contained site specific settings like for example start page id and SiteUrl. Now sites are defined in database through EPiServer.Web.SiteDefinitionRepository. Settings that are common for all sites have been moved to a new element applicationSettings under episerver element as follows:

<episerver>
   <applicationSettings httpCacheability="Public"....
   ...
</episerver>

The class EPiServer.Configuration.Settings that previously contained the settings for element siteSettings now contains the settings for element applicationSettings. Site-specific values like startPageId and SiteUrl have been obsoleted on the class Settings.

Sites can be defined in admin mode under Manage websites. To work programmatically with sites you can either use EPiServer.Web.SiteDefinitionRepository or you can use static property EPiServer.Web.SiteDefinition.Current. The property will resolve which SiteDefinition to use by checking the host on the current HttpRequest and compare which site that matches the host. In case no site matches the host or in case the code is not executing under an HTTP request the SiteDefinition that has a wildcard host '*' will be returned. If no wildcard site is defined the default SiteDefinition will be returned which has common values (for example root page) but site-specific values like SiteUrl and StartPage is not set.

ContentFolder no longer implements ILocalizable

The class EPiServer.Core.ContentFolder no longer implements interface EPiServer.Core.ILocalizable meaning folders no longer supports multi language and hence a folder will appear with same name in Block and Media gadgets regardless which language is selected in edit UI. During upgrade all other language versions than master language of folders will be deleted.

New methods added to IContentLoader

Two overloaded methods TryGet<T> have been added to interface EPiServer.IContentLoader to avoid usage of try/catch(ContentNotFoundException) pattern.

Behavior change for ContentProvider

Due to the above introducing of TryGet<T> the recommendation is that a ContentProvider should not throw ContentNotFound exception from LoadContent implementation but instead return null if a content item does not exist.

Translation of content types has moved to be generic

If you had translated pages and blocks on the site, the translation for those should now be placed under the node <contenttypes>. Example:

<contenttypes>
      <!-- Content type specific translations -->
      <pagelistblock>
         <name>Page List</name>
         <description>Displays a list of pages, for example to display recent news</description>
          <properties>
            <disableindexing>
                <caption>Disable indexing</caption>
                <help>Prevents the page from being indexed by search engines</help>
            </disableindexing>
            </properties>
      </pagelistblock>
      <!-- Common translations -->
      <icontentdata>
         <properties>
            <disableindexing>
                <caption>Disable indexing</caption>
                <help>Prevents the page from being indexed by search engines</help>
            </disableindexing>
         </properties>
      </icontentdata>  
</contenttypes>

<groups>
   <news>My translated name for news</news>   
</groups>

This will affect existing translations for pages and blocks when upgrading from CMS 7 and pages when upgrading from CMS 5 or 6. Translations that should affect all content types should be placed under the node icontentdata instead of the name of a specific content type. Any existing writable files under either "lang" or "resources/languagefiles" will be updated automatically.

PropertyValueType of PropertyWeekday changed from Int32 to Weekday

Weekday is a flags enum with corresponding values of the old integer that was returned. This has the following major implications:

The property Value will return an object of the type Weekday instead of an integer. You can cast the Weekday to an integer if your code expects that.

When registering a property weekday on your content type you should declare it using the type Weekday. So instead of:

1

[UIHint(``"WeekDay"``)]

2

public virtual int CakeDay { get``; set``; }

You should use:

1

public virtual Weekday CakeDay { get``; set``; }

Removed support for Decimal (and Int64) in typed models

Values was downconverted/upconverted when saved in the database. Decimal was converted to a Double and Int64 was converted to Int32. Since this might lead to data loss the support for Decimal and Int64 was removed from typed models. If you need to get back your values you should be able to change the type of your property to Double if you were using Decimal and Int32 if you were using Int64, since that's what it is stored as.

The method Move in IContentRepository returns ContentReference instead of void

The method Move in IContentRepository returns ContentReference instead of void, for example when moving content between different content providers you will get the correct new identity as a return value.

1

ContentReference Move(ContentReference contentLink, ContentReference destination, AccessLevel requiredSourceAccess, AccessLevel requiredDestinationAccess);

CMS administrative user interface

  • The old administrative interface that previously was mapped by virtual path providers through ProgramFiles is removed and moved into the existing CMS UI add-on. Legacy edit mode is no longer supported and old functionality there is removed.
  • Some settings for configuring TinyMCE have been removed since they were only used when using TinyMCE on the website and not in the editorial user interface. Using the built-in version of TinyMCE on the website is no longer a supported scenario. If you want to use TinyMCE on your website, we recommend downloading a separate version for this.

CMS editorial user interface

  • Dynamic properties / Dynamic content functionality is still using the CMS 6 style property editing, and does not currently support the media system in EPiServer 7.5. This means that some functionality will be limited, and affects properties that select files as well as the ability to select files in Tiny MCE. Instead of getting a file selection dialog, the user will be presented with a simple text box where the user can enter the URL to the file.
  • Quick Links gadget has been removed.
  • "epi/shell/profile": The get method is refactored. Now you can specify a location for where you store the values, see EPiServer CMS SDK.

Strict language routing

The routing has been changed so it is more strict for language handling. As an example say that there is a page under root named “News” in English and “Nyheter” in Swedish. Previously the following URLs where handled as follows (given that no language mapping is defined for site hosts in config):

  • http://localhost/News/ (page in language given by context, typically globalization setting in web.config, for example, en)
  • http://localhost/en/News/ (page in English)
  • http://localhost/sv/Nyheter/ (page in Swedish)
  • http://localhost/Nyheter/ (page in English since no language info in URL, Get language as in point 1)
  • http://localhost/en/Nyheter/ (page in English since language segment states English)

With the strict language routing the above URLs will be handled as follows:

  • http://localhost/News/ (404 since when not having language-host mapping in config, language segment must be present)
  • http://localhost/en/News/ (page in English)
  • http://localhost/sv/Nyheter/ (page in Swedish)
  • http://localhost/Nyheter/ (404 as in point 1)
  • http://localhost/en/Nyheter/ (404 since language for page with URL segment does not match language segment)

Another change is that when a language to host mapping is defined then a URL like http://localhost/en/News/ will give a 404 since when there is a host mapping that defines a language then the language should not be present in URL.

Simple address routing has also been changed so language segment must not be present. Also a simple address to a language that is different than a language-host mapping will give a 404. There is a configuration setting strictLanguageRouting on configuration element applicationSettings that can be set to false to get the old more tolerant behavior.

Typed model scanning

To be able to support that any EPiServer.Core.IContent implementation can be registered using ContentTypeAttribute some changes in the API has taken place. The types BlockTypeModelScanner and PageTypeModelScanner have been removed and instead have the former base class ContentTypeModelScanner been rewritten so it handles all content types. So, in case you have written some code that hooks into typed model synchronization, you might be affected by a binary breaking change.

AvailablePageTypesAttribute

The attribute AvailablePageTypesAttribute has been superseded by a new attribute called AvailableContentTypesAttribute with identical functionality. You need to update any code and remove all references to the namespace EPiServer.DataAbstraction.PageTypeAvailability. Due to naming conflicts the old attribute was removed instead of obsoleted to give more accurate error messages in Visual Studio.

Render template overrides

The DefaultMvcController and DefaultWebFormTemplate properties of EPiServer.DataAbstraction.ContentType are no longer set unless render templates are specifically set. To get the default template instead use the TemplateModelSelector.GetDefault method with the ContentType’s SupportedTemplates property. This will return the selected template, as defined in admin mode, or by its type argument and by whether it is an MVC controller or WebForms template (most specific type argument and MVC controllers take precedence).

New catalog structure in CMS installation

To make it possible for XCOPY deployment to a “clean machine”, the default catalog structure for the CMS installation was changed from:

  • C:\\EPiServer\\Sites\\ExampleEPiServerSite
  • C:\\EPIServer\\VPP\\ExampleEPiServerSite

To new:

  • C:\\EPiServer\\ExampleEPiServerSite\\wwwroot
  • C:\\EPiServer\\ExampleEPiServerSite\\appdata

This also involves changing to relative paths in the configuration. At installation/upgrading, the legacy user interface files have been moved to the appdata folder to avoid the connection to the Program files folder. This is done in order to make deployment of entire sites to source control and arbitrary machines.

VPP system

The VPP system is no longer used for storing editor generated content, which means that all CMS extensions to the VPP system are being phased out. The VPP API defined in EPiServer Framework will continue to be used for mapping in folders such as add-ons. See separate article on migrating to the new system.

Page objects

The PageObjectManager class have been marked obsolete as of this version but is fully backwards compatible. It will be removed in the next version, we recommend using other technologies such as blocks or custom DDS stores depending on your requirements.

Web parts

The sample templates in CMS 5 had a template that was using a Web Parts Framework built into CMS (that extended ASP.NET Web Parts). This Framework have been kept for backwards compatibility but has now been removed from the product, existing solutions built on the CMS 5 Framework for Web Parts have to be rebuilt to be able to upgrade to this version.

EPiServer.Blog

The sample templates in CMS 5/6 had a template that was using a component EPiServer.Blog and EPiServer.XmlRpc which no longer ships with the product, on upgrade these components and its config will be removed. If you are using this template you can request a compatibility package from EPiServer Support.

EPiServer.WebDav

The WebDav module made it possible to work with VirtualPathProvider (VPP) based files through a WebDav client. Since VPP based files are phased out in favor of new content-based files the EPiServer.WebDav component no longer ships with the product and will be removed during upgrade.

Subscription

The Subscription feature used in the CMS 4/5/6 templates, which automatically sends mail on publish, have been marked obsolete in this version. Existing solutions will continue to work but we do not recommend building new solutions on this API, it will be phased out.

Event configuration

Event configuration key in the load balanced or enterprise environment was changed to use HostingEnvironment.SiteName instead of siteId. If you have used enterprise configuration for events then you need to change it to the name of site from IIS.

Change <service name="{siteID}/EpiServer.Event.remote.EventReplication" /> to <service name="{siteName}/EpiServer.Event.remote.EventReplication" />.

If you have configured events with a private web config file then you need to change it from {siteId}\_Web.config to {siteName}\_web.config.

Mirroring configuration

The mirroring sites configuration in the mirroring service web config has been removed. If you have used this configuration you need to change it by defining sourceConnectionStringName and destinationConnectionStringName on the provider. If a mirroring service acts both source and destination you can also define the these attributes to achieve the same functionality as before.

Data store configuration (episerver.dataStore)

The siteDataSettings which is collection of siteDataSettingsElement on the EPiServer data store configuration element has been removed. You can use the dataSettings element instead. These settings are not defined by default in configuration.

Workflows

The workflow extensions in CMS is based on Windows Workflow Foundation 3.5 which Microsoft has obsoleted as of Microsoft .NET 4.5. We do not recommend building new Workflow solutions on this framework. It will be removed in future versions of EPiServer CMS.

TinyMCE plugin: EPiLink

EPiLink TinyMCE plugin has been moved from Cms.UI to Cms.Shell.UI/UI/Editor/TinyMCE/Plugins/EPiLinks.cs.

Configuration of the target property for block property types

In some cases a page will contain a block typed property. You can set up this block type to have a target property which will be the target for drag and drop operations in on-page edit mode. When the block overlay receives a drag and drop operation it can direct the new value to the target property.

The configuration needed to set the target property of a drag-and-drop operation on a block property type has been simplified. Previously, you had to add an editor descriptor for the block and add configuration for the sub property that should behave as the drag and drop target when in on-page edit mode. Now you only have to add the attribute DefaultDragAndDropTarget to the property on the model class. For example:

public class LogoBlock : BlockData
{
    \[UIHint(UIHint.Image)\]
    \[DefaultDragAndDropTarget\]
    public virtual ContentReference Image { get; set; }
}

Access control list

The AccessControlList and ContentAccessControlList has been slightly reworked to provide a more consistent and predictable behavior. A number of small changes could affect code dependent on one of these specific behaviors.

  • AccessControlList no longer implements IQueryableSecurityDescriptor
  • Any methods on AccessControlList that manipulates its entries will now throw an exception if the instance is inherited. This includes Clear, Remove and the Item indexer.
  • The Item indexer of AccessControlList will now allow adding new entries, not just replacing previous entries.
  • Remove method on AccessControlList now returns a boolean indicating whether an entry actually was removed or not.
  • RemoveEntry method on ContentAccessControlList has now been moved to AccessControlList and it will now compare the whole entry for a match rather than just the name.
  • ContentAccessControlList constructors that takes initial data will no longer raise the IsModified flag.
  • Some methods on AccessControlList will now throw ArgumentNullExceptions when passed null arguments rather than a NullReferenceException.

In addition the following changes has been introduced:

  • Introduced interface IEditableSecurityDescriptor that takes everything not content related from IContentSecurityDescriptor and applied it to the base AccessControlList class.
  • IQueryableSecurityDescriptor has been made obsolete as it did not really add any additional functionality over ISecurityDescriptor.
  • AccessControlList members and argument with somewhat confusing names has been replaced by more explicit and consistent equivalents. Old methods are maintained as deprecated.

PageProvider is obsoleted

The PageProviderBase was removed and the custom page provider should be converted to content provider by inherits from the EPiServer.Core.ContentProvider. The Pageprovider configuration has been changed to ContentProvider see the following sample configuration:

<contentProvider>
       <providers>
        <add capabilities="EPiServer.Core.ContentProviderCapabilities"
               entryPoint="int"
               iconPath="string"
               name="string"
               pageFolderVirtualPathProvider="string"
               supportedVirtualPathProvider="string"
               type="string"
               wastebasketName=string />
          ...
      </providers>
 </contentProvider>

Changes to CacheManager

The recommendation is to take a dependency on ISynchronizedObjectInstanceCache instead of using the CacheManager class. This was done / will be done for all Optimizely code. The new interface has been written to be able to replace the underlying HttpRuntime.Cache with other implementations. However you can continue to use CacheManager as before, including the methods that take a CacheDependency argument, since the underlying default implementation still rely on HttpRuntime.Cache. However it is strongly recommended to use the method Insert(string key, object value, CacheEvictionPolicy policy) if you need to control caching behavior.

Container page is no longer considered as a built in "system type"

When container pages was introduced with CMS 6 R2 there was a one to one mapping between pages and templates. With the release of CMS 7 a greater flexibility of adding template was added. Another big change was the conceptual change that a template defined what it can render rather than a content type assigning its template. With CMS 7.5 the ability to define the icon used for a given content type we have moved the concept of "container pages" to be a template implementation instead. You can still have content types without public templates but to get the specific "Container page" icon, you need to add a small piece of code configuration. This is part of the Alloy templates and looks as the code below:

\[UIDescriptorRegistration\]
public class ContainerPageUIDescriptor : UIDescriptor<ContainerPage>
{
    public ContainerPageUIDescriptor()
        : base(ContentTypeClassNames.Container)
    {
        DefaultView = CmsViewNames.AllPropertiesView;
    }
}

SystemPageBase was made obsolete

The base class SystemPageBase was made obsolete. Instead, you can use either WebFormsBase or ContentWebFormsBase that are located in the EPiServer.Shell.WebForms namespace in the EPiServer.UI assembly. As a side note, none of the namespaces in the EPiServer.UI assembly, except the newly added classes in the EPiServer.Shell namespace, are intended for public usage. They will, however, remain as long as there are need for them in the built in user interface (mostly the administrative interface).