SuperAPI AI 工具集

umbraco-nullable-reference-types

编程与开发

查看项目

更新于 10-22 05:17

技能介绍

用途

该技能用于在 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 断言。资料未提供收费、价格或平台要求等信息。