Block type selection doesn't work
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?
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:
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.
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
SEO redirects in .NET + Optimizely
Nice and easy way to add necessary SEO redirects
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?
Global Components Builders
Implementing global common components every site consists of