BlogBlock type selection doesn't work

Block type selection doesn't work

OptimizelyCMS 11CMSBugsUI
4 November 2024

Imagine you're trying to create a new block in a specific content area. You click the "Create" link, expecting to see a CMS modal with a list of available blocks. Instead, you're greeted with an empty view and a console error. What's going on?

Browser console errors

This is precisely the case I worked on recently in a project still running on CMS 11. Tackling issues where the UI breaks without an apparent reason is always intriguing. After several hours of using the browser's debugger mode and delving into the inner workings of the CMS, I finally uncovered the cause.

A problem

When a user clicks to create a block in the content area, a list should appear, and subsequently, the local block should be created in the "For this page" folder. However, instead, the view looks like this:

UI when an error appears

Additionally, there is a JS error in the console and in the Network tab, it can be found that one of the requests returns 404.

/EPiServer/cms/Stores/contenttype/?query=getsuggestedcontenttypes&localAsset=true&parentReference=34647_142448&requestedTypes=episerver.core.blockdata&dojo.preventCache=1728643643176

However, there are no additional logs from the backend, making it less obvious what's causing the issue.

Console error

Interestingly, this issue didn't affect all content areas. It only occurred in specific ones, within certain page instances, without any discernible pattern.

A reason

The problem originated in the UI Content Type store, which is essentially a REST API that the CMS UI connects to. After investigating the EPiServer.UI.Shell assembly, I discovered that it attempts to fetch suggestions for block types. These are the block types typically displayed at the top—usually recent types used in the specific context. The service responsible for returning these suggestions is called IContentTypeAdvisor. After injecting my mocked implementation, I pinpointed the source of the problem. To be more precise: the ContentAssetID of the parent page was incorrect, and for some reason, it couldn't be resolved in the database. This resulted in an internal exception that propagated to the upper layers, ultimately breaking the Content Type store's response.

A solution

To fix this issue, it was sufficient to remove the default implementation of the IContentTypeAdvisor from the dependency injection container.

context.Services.RemoveAll(typeof(IContentTypeAdvisor));
context.Services.AddTransient<IContentTypeAdvisor, SafeContentTypeAdvisor>();

Of course, block suggestions still needed to function. To achieve this, I created my own implementation of the service. This implementation essentially acts as a wrapper that catches any exception, allowing the Store API to continue working. In case of an error, it simply returns an empty collection.

internal class SafeContentTypeAdvisor : DefaultContentTypeAdvisor
{
    public SafeContentTypeAdvisor(
        ContentTypeAvailabilityService contentTypeAvailablilityService, 
        IContentLoader contentLoader, 
        FilterContentTypes filterContentTypes) : base(contentTypeAvailablilityService, contentLoader, filterContentTypes)
    {
    }
    
    public override IEnumerable<int> GetSuggestions(IContent parent, bool contentFolder, IEnumerable<string> requestedTypes)
    {
        try
        {
            return base.GetSuggestions(parent, contentFolder, requestedTypes);
        }
        catch (Exception)
        {
            return Enumerable.Empty<int>();
        }
    }
}

Problem solved! Editors can now create local blocks again without issues.

More articles

Hand with puzzles
OptimizelySaaSCMSCoveoSearch

Optimizely SaaS CMS + Coveo Search Page

Short on time but need a listing feature with filters, pagination, and sorting? Create a fully functional Coveo-powered search page driven by data from the Optimizely SaaS CMS - all during just a break between coffee refills.

Photo by Merakist on Unsplash
SEO.NETOptimizely

SEO redirects in .NET + Optimizely

Nice and easy way to add necessary SEO redirects

Magnifying glass
OptimizelySearchAutocomplete

Optimizely Autocomplete (Statistics)

A user starts typing in the search input, and it returns suggestions for phrases they might be searching for. How to achieve this?

Colorful lego bricks
.NETOptimizelyWeb DevelopmentDesign Patterns

Global Components Builders

Implementing global common components every site consists of

Have a question?

Don't hesitate, and send me an email

smutek.damian95@gmail.com