当我为ViewBag分配一个可以为空的整数时,它会使值无法取消?

时间:2014-03-31 15:12:19

标签: c# asp.net-mvc asp.net-mvc-5 nullable

考虑这个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>类型,而是intnull

这是ViewBag这样做吗?或者,像这样的拳击Nullable类型是否更为基础?或者,别的什么?

还有其他办法吗?

(我想我可以将支票更改为ViewBag.MyInt == null,但由于某种原因,我假装我真的需要Nullable类型。

3 个答案:

答案 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 HarveyASP.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。