考虑这个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
类型。
答案 0 :(得分:3)
我建议您创建一个视图模型,它将为您提供充分的灵活性,使“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>
}
就个人而言,我会使用viewmodel作为最佳实践,我很少使用ViewBag,除非它是非常简单的场景。
答案 1 :(得分:0)
我不确定原因,但你总是可以在视图中将其视为可以为空。
<p>MyInt.HasValue: @(((int?)MyInt).HasValue)</p>
虽然看起来有点矫枉过正。
答案 2 :(得分:0)
ViewBag是一个DynamicViewDataDictionary对象(请参阅answer by Robert Harvey和ASP.NET source code)。
Nullable是一种值类型,当您将其添加到ViewBag时会被装箱。 See this article, and especially remarks, on MSDN。根据同一篇文章,“当一个可空类型被装箱时,CLR会自动装入Nullable对象的基础值”......
将ViewBag属性测试为null是安全的。如果它不为null,则实际值是原始Nullable对象的基础类型的值。因此,此代码有效:
$ shopt -s globstar
$ a=( **/* )
$ for x in "${!a[@]}"; do [[ "${a[$x]}" = tmp3/* ]] && unset a[$x]; done
甚至这个:
@if (ViewBag.MyInt != null)
{
<p>@ViewBag.MyInt</p>
}
如果未在ViewBag中设置MyInt,则null值将呈现为空白。如果通过赋值Nullable来设置它,则实际值为int。