提问人:user2609980 提问时间:7/26/2014 最后编辑:user2609980 更新时间:7/26/2014 访问量:258
NullReferenceException 来自生产中我无法在本地重现的任何方法
NullReferenceException from Any method in production that I cannot reproduce locally
问:
当我查看我们的 MVC4 网站时,除其他外,该网站可用于制作时间表并转到 /Timetable,我看到错误消息:
System.NullReferenceException:对象引用未设置为实例 对象。(...)
堆栈跟踪: [NullReferenceException:对象引用未设置为 对象。
ASP._Page_Views_Timetable_Index_cshtml.b__5 (附表 s) +54
System.Linq.Enumerable.Any(IEnumerable2 谓词) +146 ASP._Page_Views_Timetable_Index_cshtml。执行() +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 (...)1 source, Func
这是不可取的。不幸的是,我无法在生产中将编译模式放入调试中,并且在本地我无法重现该错误。我确实想修复它,我希望这里有人可以帮助我。我将提供我解决问题的尝试,并希望您愿意一起思考:
查看上面的堆栈跟踪,我看到一个调用,控制器上只有两个调用,一个调用。Any()
Any()
Timetable/Index.cshtml
我们有一个 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
在具有 Timetable 视图上,我们有以下代码,该代码在检查后发生: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 可能会抛出 NullReferenceException。我想知道的是,在视图上是否有可能返回,从而抛出上面的异常?或者可以在控制器上做一个检查?Any()
null
schedule.GetActiveAssociatedProposals()
Timetable
null
if (!schedules.Any(s => s.Date.Equals(DateTime.Now.Date)))
null
如果是这样,则可以通过在执行检查之前检查某些属性是否存在来解决该问题。我希望有人能告诉我是否确实如此,并给我一个如何实现 -checks 的开始!null
null
答:
Any 可以返回 null,但在这种情况下,是 lambda 抛出 null。
从堆栈跟踪:
ASP._Page_Views_Timetable_Index_cshtml.b__5(Schedule s) +54
b__5
表示是由 内部使用的 lambda 创建的内部类。Any
if (!schedules.Any(s => s.Date.Equals(DateTime.Now.Date)))
我的猜测是 null,所以列表不是空的,而是包含一个 null 元素。s
编辑:哎呀,错了Any
@if (Model.Schedules.Any(s => s.User.Name.Equals(User.Identity.Name)))
这更有意义。 可以是 null,也可以是 null。User
Name
评论
b_5
表示内部类。哇,你怎么知道你不介意我问?问了这个问题,该表不允许所有列都使用 NULL,所以我不明白怎么可能包含 null 元素?Schedules
db.Schedules.Where(s => dates.Contains(s.Date)).ToList()
Schedule
UserId
User
Name
s
@if (Model.Schedules.Any(s => s.User != null && s.User.Name != null && s.User.Name.Equals(User.Identity.Name)))
评论