.NET环境下Razor模板访问Nullable DateTime报空引用错误问询
更新
经测试该问题在.NET 4.7.2环境下也可复现。
原始问题
我在netcoreapp3.1的Razor模板中使用DateTime?类型时遇到异常,模板通过如下方法调用:
Engine.Razor.RunCompile("templateName", "templateKey", model: model);
传入的模型包含属性:
public DateTime? IssueDate { get; set; }
模板内以下代码触发空引用错误:
<td>Issue date: @(result.IssueDate.HasValue ? result.IssueDate.Value.ToString("dd/MM/yyyy") : "")</td>
报错信息:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot perform runtime binding on a null reference
经调试将代码修改为如下形式即可正常运行:
<td>Issue date: @(result.IssueDate != null? result.IssueDate.ToString("dd/MM/yyyy") : "")</td>
原因说明
该报错由Razor引擎的动态绑定逻辑导致:
- 未显式声明强类型的Razor模板会默认将传入模型视为
dynamic类型,所有属性访问都在运行时做动态解析,没有编译时类型校验。 - 当
IssueDate为null时,动态绑定器不会将其识别为Nullable<DateTime>类型的实例,只会判定为普通null引用,此时访问null的.HasValue属性就会触发运行时绑定的空引用异常。 - 修改后的写法先直接判断
IssueDate是否为null,该操作不需要访问null对象的属性,动态绑定器可直接处理;同时Nullable<T>重写了ToString()方法,非空时直接调用即可输出格式化日期,无需显式访问.Value属性,因此可以正常运行。
如果要规避这类问题,可以在Razor模板开头显式声明模型的强类型,将属性校验提前到编译阶段,避免运行时绑定异常。
内容的提问来源于stack exchange,提问作者Zze
相关产品推荐
相关产品推荐

