我对此感到困惑。用户在执行回发时会随机获取空引用异常。在我看来,问题来自模型绑定器以及可能解析属性的顺序。只是想看看是否有人有任何意见?我没有能够复制调试,只能在回发中随机生成。
相当简单 ViewModel :
public class ViewModel
{
public Load Load { get; set; }
public bool ReadOnly
{
get
{
return this.GetStatus(Load.Date);
}
}
public Load PrevLoad { get; set; }
private bool GetStatus(DateTime? date)
{
if (date != null)
{
if (date.Value.DayOfWeek == DayOfWeek.Monday)
date = date.Value.AddDays(-2);
return ((DateTime.Now.AbsoluteEnd() - date.Value.AbsoluteEnd()).TotalHours) <= -24 ? false : true;
}
else
return true;
}
}
StackTrace (注意我x&#39; out out business sensitive namespaces):
System.Reflection.TargetInvocationException: Property accessor 'ReadOnly' on object
'XXX.XX.XXX.XXX.ViewModel' threw the following exception:'Object reference not set to an instance of an object.' ---> System.NullReferenceException: Object reference not set to an instance of an object.
at XXX.XX.XXX.ViewModels.ViewModel.get_ReadOnly()
--- End of inner exception stack trace ---
at System.ComponentModel.ReflectPropertyDescriptor.GetValue(Object component)
at System.Web.Mvc.DataAnnotationsModelValidator.<Validate>d__15.MoveNext()
at System.Web.Mvc.ModelValidator.CompositeModelValidator.<Validate>d__1.MoveNext()
at System.Web.Mvc.DefaultModelBinder.OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
at System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
at System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)
at System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass1e.<BeginInvokeAction>b__16(AsyncCallback asyncCallback, Object asyncState)
当我将null传递给this.GetStatus时,我得到一个不同的异常;所以我知道不可能。
你认为这会引发一个异常,因为在发生modelBinding时以及在尝试访问this.GetSatus时,技术上不存在ViewModel的实例吗?这仍然无法解释为什么有时会发生这种情况。
答案 0 :(得分:1)
根据堆栈跟踪的第一行:
at XXX.XX.XXX.ViewModels.ViewModel.get_ReadOnly()
例外是来自这里:
public bool ReadOnly
{
get
{
return this.GetStatus(Load.Date);
}
}
假设this
永远不会null
,那就离开Load
。查看视图模型的其余部分,Load
永远不会被显式初始化。视图模型假定在创建视图模型时将设置Load
。如果情况并非如此,那么期待这个例外。
此外,在堆栈跟踪中,框架似乎正在尝试读取视图模型上的属性以执行某些验证。这个特殊的视图模型假设Load
将在它被读取之前被初始化,这不是一个非常安全的假设。
一种方法可能是在视图模型中初始化Load
:
public ViewModel()
{
this.Load = new Load();
}
只要相同的假设不存在于堆栈的其他位置,这至少可以确保Load
不会为您提供NullReferenceException
。
一般而言,任何给定模型的内部责任都应该是在有效状态下构建自己。永远不要假设消费代码会设置所有属性。