回发时的随机NullReferenceException

时间:2014-09-18 19:38:24

标签: c# asp.net-mvc

我对此感到困惑。用户在执行回发时会随机获取空引用异常。在我看来,问题来自模型绑定器以及可能解析属性的顺序。只是想看看是否有人有任何意见?我没有能够复制调试,只能在回发中随机生成

相当简单 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的实例吗?这仍然无法解释为什么有时会发生这种情况。

1 个答案:

答案 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

一般而言,任何给定模型的内部责任都应该是在有效状态下构建自己。永远不要假设消费代码会设置所有属性。