Это именно тот случай, над которым я недавно работал в проекте, который все еще работает на CMS 11. Решение проблем, когда пользовательский интерфейс ломается без видимой причины, всегда интригует. После нескольких часов использования режима отладчика браузера и изучения внутренней работы CMS я наконец обнаружил причину.
Проблема
Когда пользователь нажимает кнопку создания блока в области контента, должен появиться список, после чего в папке «Для этой страницы» должен быть создан локальный блок. Однако вместо этого представление выглядит следующим образом:
Дополнительно в консоли есть JS ошибка и на вкладке Сеть видно, что один из запросов возвращает 404.
/EPiServer/cms/Store/contenttype/?query=getsuggestedcontenttypes&localAsset=true&parentReference=34647_142448&requestedTypes=episerver.core.blockdata&dojo.preventCache=1728643643176
Однако дополнительные журналы серверной части отсутствуют, что делает менее очевидным причину проблемы.

Интересно, что эта проблема затронула не все области контента. Это происходило только в определенных случаях, на определенных экземплярах страниц, без какой-либо заметной закономерности.
Причина
Проблема возникла в хранилище типов контента пользовательского интерфейса, которое по сути представляет собой REST API, к которому подключается пользовательский интерфейс CMS. Изучив сборку EPiServer.UI.Shell, я обнаружил, что она пытается получить предложения по типам блоков. Это типы блоков, которые обычно отображаются вверху — обычно это недавние типы, используемые в конкретном контексте. Служба, отвечающая за возврат этих предложений, называется IContentTypeAdvisor. После внедрения моей смоделированной реализации я определил источник проблемы. Точнее: ContentAssetID родительской страницы был неправильным и по какой-то причине его не удалось разрешить в базе данных. Это привело к внутреннему исключению, которое распространилось на верхние уровни, что в конечном итоге привело к нарушению ответа хранилища типов контента.
Решение
Чтобы устранить эту проблему, достаточно было удалить реализацию IContentTypeAdvisor по умолчанию из контейнера внедрения зависимостей.
context.Services.RemoveAll(typeof(IContentTypeAdvisor));
context.Services.AddTransient();
Конечно, предложения блоков по-прежнему должны функционировать. Для этого я создал собственную реализацию сервиса. Эта реализация по сути действует как оболочка, которая перехватывает любое исключение, позволяя Store API продолжать работу. В случае ошибки он просто возвращает пустую коллекцию.
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>();
}
}
}
Проблема решена! Редакторы теперь могут снова без проблем создавать локальные блоки.
