本技能面向 Umbraco 17+ 的服务端开发,核心是利用 Umbraco 通知机制,在系统发生特定事件时执行 C# 代码。Umbraco 为大多数操作发布通知,通常成对出现“before/after”(例如 ContentPublishingNotification 与 ContentPublishedNotification)。开发者通过注册处理程序类响应通知,也可以发布自定义通知。
使用前提:如果需求只是在发布、取消发布、删除或媒体保存/删除时向某个 URL 发起 HTTP 调用,内置 Webhooks(Settings > Webhooks)无需写代码即可完成,应优先采用该方式。
两种做法:
- 做法 A(默认):处理内置通知。编写实现 INotificationHandler<T>(或异步变体)的处理程序,并添加一行注册代码。适用于“当 Umbraco 执行 X 时执行 Y”的场景,覆盖绝大多数需求,可用于响应甚至否决 Umbraco 自身操作。随附代码资产:assets/PublishingRuleHandler.cs、assets/NotificationHandlersComposer.cs。
- 做法 B:发布自定义通知。编写通知类、发布调用,通常还需配套处理程序。适用于事件来自自己的代码、并希望其他代码无需引用该代码即可监听的场景。随附代码资产:assets/ContentImportCompletedNotification.cs、assets/ContentImportCompletedHandler.cs。一个自行发布通知并附带处理程序的任务会同时用到两种做法。
文档要求:写代码前先打开所选做法的参考文档,并从其 assets 起步;文档页面未提及的细节(缓存刷新器负载、已取消的发布、作用域投递)只在这些参考中给出。
版本兼容性:Umbraco 17+;参考中的 API 细节已对照 Umbraco 17.5 核查,随附代码以 17 参考实例为门槛。
最佳实践:
- 选择成对通知中的“右半部分”:在“before”通知中否决或修改(CancelOperation),在“after”通知中执行副作用。“after”通知无法取消(没有 CancelOperation),而“before”的副作用即使操作失败也会执行。
- 处理程序每次通知都会新建,字段不会在调用间保留;状态应放在注入的服务中。前后通知之间可通过通知的 State 传递数据。
- “Published”在本机运行,“cache refreshed”在所有服务器运行:ContentPublishedNotification 只在发布的那台服务器上触发一次;ContentCacheRefresherNotification 在每台服务器各自缓存更新后触发,适合按服务器处理的工作(本地缓存),以及负载均衡站点中必须看到其他节点已发布状态的操作。
- 语言变化会影响触发类型:取消发布一种语言相当于发布其余语言,因此会以 ContentPublishingNotification 到达,应使用 IsPublishingCulture / IsUnpublishingCulture 判断。
- 启动处理程序要保持快速(每次启动都会运行),并以 IRuntimeState.Level == RuntimeLevel.Run 作为条件,因为安装和升级启动时也会触发。
- 注册方式应沿用项目现有做法:使用已有 IComposers,或 Program.cs 中的 CreateUmbracoBuilder() 链;若两者都没有,则使用 composer。
验证:断言位于 evals/evals.json,可用 umbraco-skill-evaluator 运行。