用途
该技能用于在 Umbraco 17+ 项目中编写和修复启用 C# 可空引用类型(NRT)的代码。Umbraco 自 v10 起以 NRT 编译,其公共 API 带有可空标注,站点开发者的许多日常调用都可能返回 null。当站点开启 <Nullable>enable</Nullable>(尤其是像 Umbraco 自身源码那样设置 WarningsAsErrors=nullable)后,编译器会标出每一处忽略可空性的代码。技能说明哪些 Umbraco API 会返回 null、为什么,以及如何逐一处理,使代码在运行时正确,而不只是让编译安静。
主要能力
按场景提供参考文档:
- 不确定某个 Umbraco 调用能否返回 null:覆盖 CS86xx 下的 Umbraco API,参见
umbraco-nullable-surface.md。 - 读取属性值、选择器、媒体、Models Builder 属性:涉及
Value<T>(...)、对值调用.Trim()/.Length、defaultValue:,参见published-content-values.md。 - 在视图外获取 UmbracoContext / UmbracoHelper:涉及
TryGetUmbracoContext、在服务/托管服务/作业中使用GetRequiredUmbracoContext(),参见accessor-try-patterns.md。 - .cshtml 模板与分部视图:涉及
@Model.Value<...>()!、对选择器值做 foreach/.Any(),参见razor-views.md。 - 开启 NRT、CS8618、自定义 helper:涉及
<Nullable>、#nullable disable、未初始化的视图模型字符串、IOptions<T>类,参见project-settings.md。
技能建议在写代码前,只打开与当前代码所涉场景对应的参考文档。assets/ 中提供一个已编译、已测试的 controller → mapper → view-model 示例,可作为该结构的起点。
使用方式要点(最佳实践)
- Umbraco API 中的
?描述的是真实内容状态(编辑器留空、被选节点被删除或未发布、没有请求因而没有 UmbracoContext),应决定页面在该状态下如何表现。 - 处理顺序:守卫 → 默认值 → 极少情况用
!。优先提前返回或is not null守卫;其次给真实默认值(?? string.Empty、空集合);仅在能证明非空时使用!并注释原因。!和#nullable disable只是让编译器安静,NullReferenceException 仍会在首个空字段处出现。 - 单独使用
defaultValue:不生效:Value<T>(alias, defaultValue: x)仅在同时传入fallback: Fallback.ToDefaultValue时应用 x,且返回类型仍为T?。 - 空白文本属性是
""而非 null:对空的 Textstring 或 Textarea 调用Value<string>()返回string.Empty,因此Value<string>("title") ?? content.Name不会回退;应使用string.IsNullOrWhiteSpace或fallback: Fallback.ToDefaultValue。当别名不在文档类型上时才会返回 null。 - 使用 Try* 访问器并处理 false:
TryGetUmbracoContext/TryGetUmbracoHelper的标注保证返回 true 时 out 值非空。在没有请求的地方不要调用GetRequiredUmbracoContext();可注入单例IPublishedContentCache做普通内容查询,或在一个工作单元内用 using 配合IUmbracoContextFactory.EnsureUmbracoContext()。 - 优先使用
Parent()/Children()扩展方法,而不是已标记[Obsolete]的IPublishedContent.Parent/.Children属性(计划在 v18 移除)。 - 不要假定视图会被检查:使用 InMemoryAuto 模型时,Razor 视图在运行时编译且不做可空分析,因此构建干净不代表 .cshtml 正确,需手工套用同样规则。
- 不要声称运行过未实际执行的构建;无法编译时应说明,并明确预期是否无警告构建、指出无法确认的部分(如假设的签名或缺失的 using)。
- 交付代码需包含 using 指令:
UmbracoContextReference位于Umbraco.Cms.Core,MediaWithCrops位于Umbraco.Cms.Core.Models。
适用场景
适用于 Umbraco 17(net10.0)项目,代码约定以 Umbraco CMS release-17.5.3 源码核对,assets/ 在该仓库固定的 Umbraco 17 上以 Nullable=enable 和 WarningsAsErrors=nullable 编译。由于 Umbraco 自 v10 起提供 NRT 标注,相关模式从 v10 起适用,但个别签名(如 Parent() 与 .Parent)在旧版本中不同,使用前需核对已安装版本。
限制
Umbraco 官方关于该主题的文档仅存在于 v13,且只是指向 Microsoft 文档的简短链接;技能中 references/ 的每个 Umbraco 特定约定均对照 v17 源码核对。验证方面,客观断言位于 evals/evals.json,用 umbraco-skill-evaluator 运行;assets/ 通过 dotnet test 校验(examples/approach-a-nullable-patterns/)在 Clean 参考主机上完成编译与 HTTP 断言。资料未提供收费、价格或平台要求等信息。