За последние несколько недель в нескольких проектах Optimizely CMS начались загадочные сбои: Поля XHtmlString перестали инициализировать TinyMCE в интерфейсе редактирования. Редактор просто отказывался загружаться, в результате чего пользователи не могли управлять форматированным текстом.
Эта проблема возникла в нескольких несвязанных проектах, поэтому было ясно, что основная причина не в коде конкретного проекта. После некоторого расследования мы объяснили сбой чем-то неожиданным: версия .NET SDK, используемая конвейером сборки Azure DevOps.
Симптом
Проекты, развернутые в Optimizely DXP, начали показывать:
- TinyMCE не инициализирует поля XHtmlString
- Окно редактора отображается в виде обычного текста
- Никакая ошибка консоли не связана непосредственно с TinyMCE.
- Предупреждение о разрешении зависимостей, указывающее на созданный
.deps.jsonфайл
Локально все работало безупречно, что еще больше запутывало вопрос.
Основная причина: Azure DevOps создавался с использованием .NET 10.
Настоящая проблема заключалась в том, что конвейер Azure DevOps использовал .NET SDK 10.0.100SDK предварительной версии/следующего поколения, не совместимо с Optimizely CMS 12.
Это привело к другой .deps.json файл генерируется во время dotnet publish. Этот файл содержал неожиданные эталонные сборки и compileOnly записи, которые препятствовали правильной загрузке платформы Optimizely UI, включая TinyMCE, в DXP.
Optimizely CMS 12 разработан и протестирован для .NET 6 и .NET 8а не .NET 10.
Как убедиться, что ваш конвейер использует неправильный SDK
Временно добавьте этот шаг в свой конвейер Azure DevOps:
- script: dotnet --info
displayName: "Show .NET SDK info"
Когда конвейер заработает, проверьте выходные данные.
Если вы видите что-то вроде:
.NET SDK:
Version: 10.0.100
тогда ваш конвейер использует неправильный SDK — и это корень сбоя TinyMCE.
Исправление: прикрепите конвейер к .NET 8
Чтобы обеспечить согласованность с локальными сборками и совместимость с DXP, добавьте следующий шаг перед восстановлением/сборкой в вашем конвейере:
- task: UseDotNet@2
displayName: "Use .NET 8 SDK"
inputs:
packageType: 'sdk'
version: '8.0.x'
Это заставляет конвейер устанавливать и использовать правильный пакет SDK для .NET 8, гарантируя, что:
- Один и тот же граф зависимостей создается локально и в DevOps.
.deps.jsonгенерируется правильно- TinyMCE нормально инициализируется в интерфейсе редактирования Optimizely.
После применения этого исправления проекты были успешно развернуты, а TinyMCE загружен без проблем.
Почему это происходит
Размещенный агент windows-latest недавно начал поставки с Предустановленные пакеты SDK предварительной версии .NET 10.
Если в вашем конвейере явно не указана версия .NET, Azure DevOps по умолчанию использует новейший доступный SDKдаже если ваш проект был создан для .NET 8.
Это означает, что SDK влияет на:
- Разрешение зависимостей
- Включение ресурсов среды выполнения
.deps.jsonпоколение
Небольшие различия здесь могут нарушить работу таких фреймворков времени выполнения, как Optimizely UI.
Рекомендуемые лучшие практики
Чтобы предотвратить подобные проблемы в будущем:
✔ Всегда закрепляйте свой SDK в процессе разработки.
Использовать UseDotNet@2 явно.
✔ Добавить global.json в корне вашего проекта
Пример:
{
"sdk": {
"version": "8.0.403",
"rollForward": "disable"
}
}
Это гарантирует, что как локальная, так и CI-среда используют один и тот же SDK.
✔ Периодически проверяйте журналы сборки
С использованием dotnet --info во время устранения неполадок помогает обнаружить непреднамеренные изменения версий на ранней стадии.
Заключение
Эта проблема с инициализацией TinyMCE оказалась отличным примером того, как среды сборки незаметно влияют на поведение во время выполнения. Даже если приложение успешно компилируется и публикуется, неожиданная версия SDK может внести незначительные изменения, которые нарушат функциональность в рабочей среде.
Явно прикрепив пакет SDK для .NET к версии 8 в Azure DevOps (и в идеале с помощью global.json файл), вы обеспечите единообразное поведение в разных средах и избежите подобных проблем.
Если вы столкнулись с подобными проблемами пользовательского интерфейса в Optimizely, проверка версии SDK в вашем конвейере должна быть одним из первых шагов.
Ещё по этой теме

