当我将一个可为空的整数分配给 ViewBag 时,它会使该值不可为空
本文关键字:ViewBag 整数 一个 分配 | 更新日期: 2023-09-27 17:55:39
考虑 ASP.NET MVC 5控制器:
public class MyController : Controller {
public ActionResult Index(int? id) {
ViewBag.MyInt = id;
return View();
}
}
而这个观点:
<p>MyInt.HasValue: @MyInt.HasValue</p>
当我调用 URL /my/
(使用空 id)时,出现以下异常:
An exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in System.Core.dll but was not handled in user code
Additional information: Cannot perform runtime binding on a null reference
相反,如果我传入一个 ID(例如,/my/1
):
An exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in System.Core.dll but was not handled in user code
Additional information: 'int' does not contain a definition for 'HasValue'
这在我看来,ViewBag.MyInt
不是Nullable<int>
型,而是int
或null
。
这是ViewBag在做这件事吗?或者,像这样装箱 Nullable 类型是否更基本?或者,别的什么?
有没有其他方法可以做到这一点?
(我想我可以将我的支票更改为ViewBag.MyInt == null
,但让我们假设我出于某种原因真的需要一个Nullable
类型)
我建议您创建一个视图模型,该模型将为您提供完全的灵活性,使"MyInt"成为可为空的类型。
当然,另一种选择是仅在不为空时才设置"MyInt"......
public class MyController : Controller {
public ActionResult Index(int? id) {
if (id.HasValue)
{
ViewBag.MyInt = id;
}
return View();
}
}
视图:
@if (ViewBag.MyInt != null)
{
<p>Has an Id</p>
}
else
{
<p>Has no Id.</p>
}
就个人而言,我会使用视图模型作为最佳实践,我很少使用 ViewBag,除非它用于非常简单的场景。
我不确定原因,但您始终可以在视图中将其转换为可为空。
<p>MyInt.HasValue: @(((int?)MyInt).HasValue)</p>
虽然,这似乎有点矫枉过正。
ViewBag 是一个 DynamicViewDataDictionary 对象(参见 Robert Harvey 的回答和 ASP.NET 源代码)。
Nullable 是一种值类型,当您将其添加到 ViewBag 时,它会被装箱。请参阅有关 MSDN 的这篇文章,尤其是备注。根据同一篇文章,"当可为空的类型被装箱时,CLR 会自动装箱 Nullable 对象的基础值"......
可以安全地测试 ViewBag 属性的空值。如果它不为 null,则实际值是原始 Nullable 对象的基础类型的值。因此,此代码有效:
@if (ViewBag.MyInt != null)
{
<p>@ViewBag.MyInt</p>
}
甚至这个:
<p>@ViewBag.MyInt</p>
如果未在 ViewBag 中设置 MyInt,则空值将呈现为空白。如果通过分配可为 Null 的值来设置它,则实际值为 int。