当我查看我们的MVC4网站时,其中包括可用于制作时间表并转到/时间表,我看到错误消息:
System.NullReferenceException:未将对象引用设置为实例 一个对象。 (...)
堆栈跟踪: [NullReferenceException:对象引用未设置为的实例 对象。]
ASP._Page_Views_Timetable_Index_cshtml.b__5(附表s)+54
System.Linq.Enumerable.Any(IEnumerable1 source, Func
2谓词) +146 ASP._Page_Views_Timetable_Index_cshtml.Execute()+ 4057 System.Web.WebPages.WebPageBase.ExecutePageHierarchy()+198
System.Web.Mvc.WebViewPage.ExecutePageHierarchy()+104
System.Web.WebPages.StartPage.RunPage()+17
System.Web.WebPages.StartPage.ExecutePageHierarchy()+64(...)
这是不可取的。不幸的是,我无法将编译模式放入生产调试中,而本地我无法重现错误。我确实想解决这个问题,我希望有人可以帮助我。我会尝试解决这个问题,并希望你愿意一起思考:
查看上面的堆栈跟踪,我看到Any()
来电,Any()
上只有两个Timetable/Index.cshtml
来电,而控制器中只有一个。{/ p>
我们有一个Schedule和Proposal模型:( Schedule用于存储Date,User和State,如果用户想要与其他用户更改日期,则使用Proposal。)
public class Schedule : IValidatableObject {
[Key]
public int ScheduleId { get; set; }
public DateTime Date { get; set; }
public int UserId { get; set; }
public virtual User User { get; set; }
public ScheduleState State { get; set; }
public virtual ICollection<Proposal> ProposalsAsSender { get; set; }
public virtual ICollection<Proposal> ProposalsAsReceiver { get; set; }
}
public class Proposal {
public int ProposalId { get; set; }
public ProposalState State { get; set; }
[InverseProperty("ProposalsAsSender")]
public virtual Schedule SenderSchedule { get; set; }
[InverseProperty("ProposalsAsReceiver")]
public virtual Schedule ReceiverSchedule { get; set; }
}
模型Proposal
上有以下两种方法:
public ICollection<Proposal> GetAssociatedProposals()
{
return ProposalsAsSender.Concat(ProposalsAsReceiver).ToList();
}
public ICollection<Proposal> GetActiveAssociatedProposals()
{
return GetAssociatedProposals()
.Where(p => p.State == ProposalState.Active)
.Where(p => p.ReceiverSchedule.State == ScheduleState.Active)
.Where(p => p.SenderSchedule.State == ScheduleState.Active)
.ToList();
}
我在本地看到的是这个方法总是返回一个空列表,但不是null
。 (可以返回null
吗?)。
还有TimetableController
个方法:
[HttpGet]
public ActionResult Index()
{
var dates = Schedule.GetCorveeDatesNextThirtyDays(); // returns dates that are not weekends
var schedulesNextThirtyDays = db.Schedules.Where(s =>
dates.Contains(s.Date)).ToList();
var schedules = schedulesNextThirtyDays.Where(s => s.State ==
ScheduleState.Active).ToList();
if (!schedules.Any(s => s.Date.Equals(DateTime.Now.Date))) //Any in controller
{
var todays_schedule = schedulesNextThirtyDays.Where(s => s.State ==
ScheduleState.Completed).FirstOrDefault(s => dates.Contains(s.Date));
if(todays_schedule != null)
schedules.Add(todays_schedule);
}
return View(new DatesAndSchedulesViewModel(dates, schedules));
}
DatesAndSchedulesViewModel
由构造函数中设置的ICollection<Schedule> Schedules
和ICollection<DateTime> Dates
组成。
在DatesAndSchedulesViewModel
为Model
的时间表视图中,我们在schedule != null
项检查后发生以下代码:
@if (Model.Schedules.Any(s => s.User.Name.Equals(User.Identity.Name))) //First Any() on view
{
if (schedule.State == ScheduleState.Active)
{
if (schedule.GetActiveAssociatedProposals().Any()) //Second Any() on view
{
<span>Do something</span>
}
}
}
我知道Linq的Any()
如果在null
上完成,则会抛出NullReferenceException。我想知道的是schedule.GetActiveAssociatedProposals()
视图中的Timetable
是否可能返回null
,因此抛出上述异常?或者控制器中的if (!schedules.Any(s => s.Date.Equals(DateTime.Now.Date)))
可以对null
进行检查吗?
如果是这样,可以通过在执行检查之前检查某些属性是否为null
来解决问题。我希望有人可以告诉我是否确实如此,并开始介绍如何实施null
- 检查!
答案 0 :(得分:3)
任何都可以返回null,但在这种情况下,它是抛出null的lambda。
来自你的堆栈跟踪:
ASP._Page_Views_Timetable_Index_cshtml.b__5(Schedule s) +54
b__5
表示这是由Any
内使用的lambda创建的内部类。
if (!schedules.Any(s => s.Date.Equals(DateTime.Now.Date)))
我的猜测是s
为空,因此列表不为空,但包含null元素。
编辑:糟糕,错误Any
@if (Model.Schedules.Any(s => s.User.Name.Equals(User.Identity.Name)))
这更有意义。 <{1}}可以为null,或User
可以为null。