[英]NullReferenceException in MVC3 Controller
我正在玩MVC3,尝试创建小型测试项目,这些项目将模拟我预期在从PHP迁移的较大项目中会遇到的问题。 在使用以下元素实例化项目中的“ model”变量时,我不断收到“ NullReferenceException”:
模型:
public class MainModel
{
public IEnumerable<Chemical> chemicals { get; set; }
}
public class Chemical
{
public int ChemicalId { get; set; }
public string Name { get; set; }
public virtual ICollection<Hazard> Hazards { get; set; }
}
public class Hazard
{
public int HazardId { get; set; }
public string Description { get; set; }
public virtual ICollection<Chemical> Chemicals { get; set; }
}
控制器:
public class MainController : Controller
{
public ActionResult Index()
{
var h1 = new Hazard { HazardId = 1, Description = "Flammable" };
var h2 = new Hazard { HazardId = 2, Description = "Carcinogen" };
var h3 = new Hazard { HazardId = 3, Description = "Water Reactive" };
var model = new [] {
new Chemical { ChemicalId = 1, Name = "Benzene", Hazards = {h1, h2}},
new Chemical { ChemicalId = 2, Name = "Sodium", Hazards = { h3 } },
new Chemical { ChemicalId = 3, Name = "Chloroform", Hazards = { h2 } },
new Chemical { ChemicalId = 4, Name = "Water" }
}; //NULL EXCEPTION THROWN HERE
return View(model);
}
}
因此,我有两个问题:
谢谢!
实际问题与MVC无关。 您正在使用匿名对象实例化ICollection Hazards
,并且我相信编译器无法正确解析此代码,因此它在运行时将失败。 快速修复方法如下:
var model = new [] {
new Chemical { ChemicalId = 1, Name = "Benzene", Hazards = new List<Hazard>{h1, h2}},
new Chemical { ChemicalId = 2, Name = "Sodium", Hazards = new List<Hazard>{ h3 } },
new Chemical { ChemicalId = 3, Name = "Chloroform", Hazards = new List<Hazard>{ h2 } },
new Chemical { ChemicalId = 4, Name = "Water" }
};
需要注意的使用List<Hazards>{h1, h2}
而不是仅仅{h1, h2}
为什么我不断收到NullReferenceException,如何解决?
ICollection
属性Hazards
最初为ICollection
创建模型时必须使用构造函数:
var model = new[] {
new Chemical { ChemicalId = 1, Name = "Benzene", Hazards = new List<Hazard>() {h1, h2}},
new Chemical { ChemicalId = 2, Name = "Sodium", Hazards = new List<Hazard>(){ h3 } },
new Chemical { ChemicalId = 3, Name = "Chloroform", Hazards = new List<Hazard>(){ h2 } },
new Chemical { ChemicalId = 4, Name = "Water" }
};
您当前拥有的代码将尝试将 {h1,h2}
到Hazards
-这是null并抛出NullReferenceException
。 一种替代方法是在Chemical
构造函数中创建一个新的空Hazards
集合-然后您可以保留当前代码不变:
public class Chemical
{
public Chemical()
{
_hazards = new List<Hazard>();
}
//..
}
由于您来自PHP,因此概述CSharp的语法快捷方式可能会更有帮助!
乍一看它们确实令人困惑,因为语法是如此相似。 但是快速介绍之后,您将学会爱他们。
集合初始化器将项目添加到集合中。 语法是new SOMECOLLECTION { value, value, value }
填充集合的传统方式:
var items = new List<int>();
items.Add(1);
items.Add(2);
items.Add(3);
集合初始化器的方式-编译成几乎相同的代码:
var items = new List<int>(){ 1, 2, 3 };
旁注: 数组与列表 -我会说List
是更常用的,因为它的大小可以改变。 但这主要是个人喜好。 创建数组的简便方法是: var items = new int[]{ 1, 2, 3 };
,但您也可以忽略该类型,编译器将找出它(又名隐式数组): var items = new []{ 1, 2, 3 };
对象初始化程序设置新对象的属性。 语法是new SOMEOBJECT { Property = value, Property = value }
填充对象属性的传统方法:
var item = new Item();
item.First = "Chuck";
item.Last = "Norris";
对象初始化方式:
var item = new Item(){ First = "Chuck", Last = "Norris" };
我之所以仅提及这一点,是因为匿名对象的语法与其他对象非常相似,但是却有很多不同。 如果您不了解它们,它们将非常令人困惑!
语法看起来像集合初始化和对象初始化的组合: new { AnyPropertyName = value, anyVariableNameBecomesAProperty, someOtherObject.SomeProperty }
让我解释! 编译器将创建一个“匿名对象”有3个属性, AnyPropertyName
, anyVariableNameBecomesAProperty
和SomeProperty
,并初始化值的方式为对象初始化不相同。 如果未指定属性名称,则从源中推断出该名称。
我希望这可以帮助您理解为什么new { h1, h2 }
(新匿名对象)与new []{ h1, h2 }
(new数组)有何不同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.