Выбор типа блока не работает

Это именно тот случай, над которым я недавно работал в проекте, который все еще работает на 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>();
        }
    }
}

Проблема решена! Редакторы теперь могут снова без проблем создавать локальные блоки.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.