I’ve now written several blog posts about my experience with Optimizely CMS 12 upgrade process on several different projects. Each project has taught me something new and made me encounter things I hadn’t before. One of my earlier upgrade projects this year had very unique challenges that I wrote about here. This time around, I’m going to share some more of my Optimizely CMS 12 upgrade takeaways that may help others on their upgrade journey.

These all came to me as strange behaviors that normally should have worked based on my experience but didn’t. So without further ado, here we go.

1. Reports tab

When Optimizely first launched CMS 12, they were indeed missing the Reports tab in the backend. This was re-introduced with CMS version 12.12 and is built using React now. However, now you cannot add custom reports to it anymore, like you did in CMS 11 using GuiPlugins. In CMS 12, you’ll need to create custom reports using MenuProviders and place then under their own menu tab now. Trying to put them under Reports tab will not work.

Another interesting thing to know about MenuProviders in this context, is that if you have a custom page built using MenuProvider and it has further click throughs using buttons, like we normally do on custom reports, for filtering, paging, sorting etc, in order to see the epi top navigation and the custom link highlighted on it, when you click on subsequent buttons, you need to make sure, all those actions (urls) are also captured in MenuProvider as MenuItems with name empty and isAvailable = context => false.

Example :

var customReportMenu = new UrlMenuItem(“Custom Report”, “/global/cms/customreport”, “/CustomReport”)
{
SortIndex = SortIndex.Last – 20,
IsAvailable = context => true
};

var customReportFilterMenu = new UrlMenuItem(string.Empty, “/global/cms/customreport/filter”, “/CustomReport/Filter”)
{
SortIndex = SortIndex.Last – 20,
IsAvailable = context => false
};

2. Optimizely Logout

If you are using custom authentication schemes in your projects, one of the things that break as a result is the default Optimizely Logout link (/util/logout). In our case, we used JWTBearerTokenAuthentication and now we couldn’t use the default logout url. So a potential workaound for this, is to override the logout url altogether and add logic to your own custom logout link.

We basically added a logout call on an api controller :

[HttpGet]
[Route(“/api/logout”)]
public async Task<IActionResult> LogoutAsync()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
return Redirect(UrlResolver.Current.GetUrl(ContentReference.StartPage));
}

And then registered that in Startup.cs :

services.ConfigureApplicationCookie(delegate (CookieAuthenticationOptions options)
{
options.LogoutPath = “/api/logout”;
});

3. Microsoft.AspNetCore packages

Ideally when we switch from Optimizely CMS 11 to 12, we also upgrade our Microsoft.AspNet libraries to Microsoft.AspNetCore ones. This simple upgrade has worked fine earlier on all the projects. However, this time around, when we looked at these, a bunch of these Microsoft.AspNetCore libraries now show as deprecated under Nuget.Org. And there is no update anywhere online from Microsoft on what to use instead now. I even opened a ticket with Microsoft on this but didn’t hear back.

So what could we do now?

We had been using these on other projects and they had been working fine still, so we figured it should be ok to still use these. So we went ahead and upgraded to these deprecated Microsoft.AspNetCore libraries. On the surface, there were no errors tied to these. However, when we got to the launching state, we started seeing issues with rendering views. Despite the correct paths and view engine setup, it couldn’t find views.

One of the developers researched and installed Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation and added the necessary registration in startup and views started rendering locally. We figured maybe that’s needed now.

However, when we deployed to DXP, this broke again. Even though the above package was there, it still started throwing the same “View couldn’t be found” error. So we were back to square one.

Actual solution?

After further research, we found that because we were now on a more latest Optimizely CMS 12 version (12.20), using the deprecated Microsoft.AspNetCore.Mvc package conflicted with the latest razor view rendering logic. Once we removed the deprecated package and the RuntimeCompilation package, it worked, both locally and on DXP.

So as a good cleanup effort, to avoid any future conflicts like these, we removed all deprecated Microsoft.AspNetCore packages from our solution. Everything still works.

If you’re starting new on an upgrade project, my recommendation would be to not install any deprecated packages at all from the beginning.

4. Visual Studio Build Acceleration feature

In February of this year, VS 2022 introduced a new feature called Build Acceleration as part of version 17.5. This reduces incremental build times of SDK style projects by up to 80%. What this really means is that it will only recompile projects that have code changes, which in turn means it won’t pick changes made to appsettings.json files as they have Build Action: None by default.

How was this a problem?

Well, I didn’t know the above before. So I was working through an issue and needed to switch to a different copy of database locally, so just needed a change on the connectionstring in my appsettings.json. I did that, ran the solution and it didn’t work as expected. I debugged the Program.cs file to see what connectionstring value it’s pulling and to my surprise, it was still the old value.

At first, I thought VS is caching this stuff for some reason. I cleared all temp and cache files but no change. After more research, I found out about this new VS feature and how it doesn’t pick up appsettings.json changes, if those are the only ones you made before launching site.

How do you fix it?

You might research and find several different solutions for this online, but the only one that worked for me so far is to do a Clean and Rebuild Solution after any appsettings.json change, so VS actually runs the whole MSBuild process and picks it up. Its frustrating because I have to do this more and more now everytime its just an appsetting change that I have to make.

I’ve been reading on forums that others have raised this as an issue and its been logged as a bug with VS team. Hopefully there will be a more sensible and cleaner solution available soon.

5. Page Tree dialog

In Optimizely CMS 11, if you ever needed to render a modal for page tree content, there were js files in the Epi Shell modules that would let you call something like Epi.CreatePageTreeDialog. This would then open an aspx page within a modal window and display the page tree hierarchy in it.

As expected, with Optimizely CMS 12, aspx pages no longer exist, and neither do these js files that enabled rendering this dialog. On the CMS Edit side, if you click on Select Content option in a Content Area, it does render a modal with page tree hierarchy but that’s built in React now. And all its logic is internal to Opti, so hard to find a way to render it yourself if needed.

So what do we do now?

After quite a bit of back and forth and reaching out to Opti community and support, we came up with a more custom solution that involved creating a custom MVC ViewComponent and vanilla javascript to enable ajax calls for expanding the page tree.

Conclusion

All in all, these aren’t crazy big things, but if you don’t know about them, they will give you major headaches with the upgrade process as things just won’t work as expected anymore. It did give me some and I had to spend a fair amount of time figuring them out, so hoping this saves others some trouble!

Do leave a comment if you have any other Optimizely CMS 12 upgrade takeaways that may help us in future projects!