对象引用未设置到对象的实例 - 多个项目 (MVC)
Object reference not set to an instance of an object - Multiple Projects (MVC)
我正在使用 Contoso 大学教程,并通过模块化尝试(模型、DAL 和 WebUI 的单独项目 - 附图中的顶部图片)和单个项目(包含所有层 - 底部图片)进行尝试).在这两种情况下,解决方案都可以正确编译。但是,当我在 Web 浏览器中转到学生的详细信息部分时,当我转到第二个断点时,模块化项目会抛出错误,开始:
异常详细信息:
System.NullReferenceException: Object reference not set to an instance of an object.
相同的模型被传递到每个项目的视图中,
@model ContosoUniversity.Models.Student
并且在以下行之后发生空引用异常:
@foreach (var item in Model.Enrollments){
我认为这可能是 ContosoUniversity.Models
项目和 ContosoUniversity 项目中的 Models 文件夹之间的命名空间冲突,但是重命名该文件夹并不能解决这个问题。是否有其他与多个项目相关的东西会导致此处遇到空值(Enrollments.cs 未发送到模型),但不是单个项目?
如果它在代码中有更深层次的东西,我可以跟进完整的视图代码和模型 类.
Screenshot of working and non working solutions in VS2015Community
由于对于新开发人员来说这是一个常见的令人困惑的错误,因此我编写了一个 post on my blog 来详细解释错误的含义以及如何调试它。 TL;DR:Object reference not set to an instance of an object
是一个运行时错误(因此你的项目编译得很好)当你期望一个变量是特定 class 的实例时发生,但它实际上解析为空运行时间。
这通常发生在您从数据库中选择对象但没有匹配项时,或者您忽略了对需要初始化的模型(如列表)初始化 属性。根据您发布的代码行,我的猜测是模型本身为 null(可能是因为它来自数据库并且您在将其发送到视图之前没有检查 null),或者 Enrollments
属性 为空,因为您忽略了对其进行初始化,或者如果您的模型是实体 class.
的实例,则它未标记为 virtual
无论何时从数据库中请求特定对象,都应始终检查是否为 null 并进行适当处理。例如,如果您正在处理 "detail" 操作,您的代码应如下所示:
public ActionResult Detail(int id)
{
var foo = db.Foos.Find(id); // potentially null, if no matching id
if (foo == null)
{
return new HttpNotFoundResult();
}
return View(foo);
}
如果您的模型中有列表样式 属性,您应该始终通过 class 构造函数或自定义 getter:
对其进行初始化
public class Foo
{
public Foo()
{
Bars = new List<Bar>();
}
public List<Bar> Bars { get; set; }
}
或
public class Foo
{
private List<Bar> bars;
public List<Bar> Bars
{
get
{
if (bars == null)
{
bars = new List<Bar>();
}
return bars;
}
set { bars = value; }
}
}
如果您使用的是 C# 6,最后一个可以简化为:
public class Foo
{
public List<Bar> Bars { get; set; } = new List<Bars>();
}
最后,如果你处理的是 Entity Framework POCO,这不是必需的,只要 属性 是 virtual
:
public virtual ICollection<Bar> Bars { get; set; }
作为延迟加载工具的一部分,Entity Framework 会自动覆盖 属性,这样它就永远不会为 null,如果那里真的什么都没有,则只会是一个空集合。但是,如果您忽略 virtual
关键字,EF 将无法执行必要的重写来处理此问题。
总而言之,您需要弄清楚哪个变量为 null 而您期望它具有实际值,然后要么进行适当的空值检查(无论如何这是一个好主意),要么弄清楚为什么它是null 而不是您期望的值。
我正在使用 Contoso 大学教程,并通过模块化尝试(模型、DAL 和 WebUI 的单独项目 - 附图中的顶部图片)和单个项目(包含所有层 - 底部图片)进行尝试).在这两种情况下,解决方案都可以正确编译。但是,当我在 Web 浏览器中转到学生的详细信息部分时,当我转到第二个断点时,模块化项目会抛出错误,开始:
异常详细信息:
System.NullReferenceException: Object reference not set to an instance of an object.
相同的模型被传递到每个项目的视图中,
@model ContosoUniversity.Models.Student
并且在以下行之后发生空引用异常:
@foreach (var item in Model.Enrollments){
我认为这可能是 ContosoUniversity.Models
项目和 ContosoUniversity 项目中的 Models 文件夹之间的命名空间冲突,但是重命名该文件夹并不能解决这个问题。是否有其他与多个项目相关的东西会导致此处遇到空值(Enrollments.cs 未发送到模型),但不是单个项目?
如果它在代码中有更深层次的东西,我可以跟进完整的视图代码和模型 类.
Screenshot of working and non working solutions in VS2015Community
由于对于新开发人员来说这是一个常见的令人困惑的错误,因此我编写了一个 post on my blog 来详细解释错误的含义以及如何调试它。 TL;DR:Object reference not set to an instance of an object
是一个运行时错误(因此你的项目编译得很好)当你期望一个变量是特定 class 的实例时发生,但它实际上解析为空运行时间。
这通常发生在您从数据库中选择对象但没有匹配项时,或者您忽略了对需要初始化的模型(如列表)初始化 属性。根据您发布的代码行,我的猜测是模型本身为 null(可能是因为它来自数据库并且您在将其发送到视图之前没有检查 null),或者 Enrollments
属性 为空,因为您忽略了对其进行初始化,或者如果您的模型是实体 class.
virtual
无论何时从数据库中请求特定对象,都应始终检查是否为 null 并进行适当处理。例如,如果您正在处理 "detail" 操作,您的代码应如下所示:
public ActionResult Detail(int id)
{
var foo = db.Foos.Find(id); // potentially null, if no matching id
if (foo == null)
{
return new HttpNotFoundResult();
}
return View(foo);
}
如果您的模型中有列表样式 属性,您应该始终通过 class 构造函数或自定义 getter:
对其进行初始化public class Foo
{
public Foo()
{
Bars = new List<Bar>();
}
public List<Bar> Bars { get; set; }
}
或
public class Foo
{
private List<Bar> bars;
public List<Bar> Bars
{
get
{
if (bars == null)
{
bars = new List<Bar>();
}
return bars;
}
set { bars = value; }
}
}
如果您使用的是 C# 6,最后一个可以简化为:
public class Foo
{
public List<Bar> Bars { get; set; } = new List<Bars>();
}
最后,如果你处理的是 Entity Framework POCO,这不是必需的,只要 属性 是 virtual
:
public virtual ICollection<Bar> Bars { get; set; }
作为延迟加载工具的一部分,Entity Framework 会自动覆盖 属性,这样它就永远不会为 null,如果那里真的什么都没有,则只会是一个空集合。但是,如果您忽略 virtual
关键字,EF 将无法执行必要的重写来处理此问题。
总而言之,您需要弄清楚哪个变量为 null 而您期望它具有实际值,然后要么进行适当的空值检查(无论如何这是一个好主意),要么弄清楚为什么它是null 而不是您期望的值。