提问人:Mahmoud Al-Qudsi 提问时间:3/21/2023 更新时间:3/21/2023 访问量:64
Razor 页面中访问本地非 null 变量的 NullReferenceException
NullReferenceException in razor page accessing local, non-null variable
问:
我在 cshtml Razor 页面中遇到了一个非常奇怪的情况,其中块中的常规代码可以很好地访问和使用变量,但是尝试访问相同的变量但在上下文中会抛出 s。@{ ... }
@(...)
NullReferenceException
为了调试这个问题,我移动了模型属性导航和对绝对非 null 的局部变量的访问,然后尝试使用块打印它,但仍然存在。@(..)
NullReferenceException
@foreach (var sibling in Model.SiblingApplications)
{
string studentName = sibling.Student.ToString() ?? "";
<div class="sibling half line">
<div class="question-block grow">
<div class="label">Name</div>
@* NullReferenceException on the next line! *@
<div class="value">@studentName</div>
</div>
</div>
}
最初,它来自直接编写,即使我在它上面添加了断言以抛出属性访问或覆盖 where 使用的任何变量。然后,我将代码重构为您在上面看到的内容,将变量存储在非 null 字符串中(并通过附加偏执狂来加倍确保这种情况)。NullReferenceException
@(sibling.Student)
ToString()
null
?? ""
尽管如此,仍然存在。我无法在调试或发布模式下本地观察到该问题,但它不会失败并记录在生产中。我尝试从 .NET 7 降级到 .NET 6,并尝试部署 Debug 版本而不是 Release,但这些都没有帮助。NullReferenceException
堆栈跟踪没有帮助;它只是指向上面注释的行:NullReferenceException
System.NullReferenceException: Object reference not set to an instance of an object.
at ProjectName.Pages.Forms.Pages_Forms_RegistrationForm.ExecuteAsync() in X:\ProjectPath\Pages\Forms\RegistrationForm.cshtml:line 240
...
重要的是,在实际访问模型属性并生成非 null 字符串的代码上不会引发异常 - 同样,异常发生在访问这个 now-local、绝对不是 null 的变量时。
答:
如果不附加调试器,我无法弄清楚这一点,之后它立即变得清晰起来。(弄清楚如何在生产中附加调试器是另一回事。
虽然异常确实是在带注释的行上引发的,但在调试器中,会显示导致异常的变量,尽管它未在记录的实际异常消息或堆栈跟踪中命名。NullReferenceException
事实证明,(由于优化?)编译器一次性取消了两个不同的值,(在同一行上使用)和(在同一个for循环中使用了几行,上面发布的缩写示例中没有显示)。@sibling.Student
@sibling.AnotherProperty
第二次访问实际上导致了 ,尽管堆栈跟踪和调试器(甚至在调试模式下附加)都在第一行的末尾抛出/中断。NullReferenceException
我以前想知道是否有可能让记录的异常和堆栈跟踪实际上包含调试器发出的相同信息(即,发生时被取消引用的属性或变量,而不仅仅是行号) - 这将为我(和你)省去很多悲伤。NullReferenceException
评论
sibling.Student
string studentName = sibling.Student?.ToString() ?? "";
sibling.Student
.ToString()
??
sibling.Student
?? ""
ToString()
sibling.Student
sibling.Student