对象引用未设置为对象的实例...但它是?

时间:2022-03-05 14:31:25

I'm having an issue with deleting an object now, earlier this week this code was working fine, but now I'm getting a null reference exception, even though the object I'm attempting to delete, and the instance of the entity framework are not null.

我现在有一个删除对象的问题,本周早些时候这段代码工作正常,但现在我得到一个空引用异常,即使我试图删除的对象,以及实体框架的实例不是空的。

    MHNHubEntities _entities = new MHNHubEntities();

    // Get, GetList, Add, Save etc.

    public void Delete(PackageProduct packageProduct)
    {
        _entities.PackageProducts.DeleteObject(packageProduct);
    }

packageProduct is a valid packageProduct, and everything else but this delete works. Normally I wouldn't ask how to solve a null reference exception - because its fairly obvious, check for nulls. However - in this case I'm stumped, what was working yesterday suddenly isn't and this is whats throwing the exception. Any help would be appreciated, I've already confirmed there are no null objects involved when this exception is thrown.

packageProduct是一个有效的packageProduct,除此删除之外的所有其他内容都有效。通常我不会问如何解决空引用异常 - 因为它非常明显,检查空值。然而 - 在这种情况下,我很难过,昨天突然发生的事情不是,这就是抛出异常的原因。任何帮助将不胜感激,我已经确认抛出此异常时不涉及空对象。

edit

I don't want to rule out that something is null and causing this - because of the very nature of the exception being thrown. As per request, here is the stack trace:

我不想排除某些东西是空的并导致这种情况 - 因为抛出异常的本质。根据请求,这里是堆栈跟踪:

   at MHNHub.Areas.Store.Controllers.SettingsController.DeletePackage(Int32 id, FormCollection collection) in C:\Users\Grahame\Desktop\Projects\MHN Hub\Visual Studio Project\MHNHub\MHNHub\Areas\Store\Controllers\SettingsController.cs:line 618
   at lambda_method(Closure , ControllerBase , Object[] )
   at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
   at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.<InvokeActionMethodWithFilters>b__a()
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)

Heres my controller action:

继承我的控制器动作:

  [HttpGet]
        public ActionResult DeletePackage(int id, FormCollection collection)
        {
            try
            {

                IPackageRepository packageRepository = new PackageRepository();
                var package = packageRepository.GetPackage(id);

                IPackageProductRepository packageProductRepository = new PackageProductRepository();
                var packageProducts = package.PackageProducts.ToList();

                foreach (var packageProduct in packageProducts)
                {
                    packageProductRepository.Delete(packageProduct);
                }

                packageRepository.Delete(package);
                packageRepository.Save();

                return Json(new { Success = "true" }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                //return JSON with exception
                var result = new { Message = ex.Message, InnerException = ex.InnerException.ToString() };

                return Json(result, JsonRequestBehavior.AllowGet);
            }
        }

4 个解决方案

#1


5  

Well, if it's making it as far as this line:

好吧,如果它正在这条线上:

_entities.PackageProducts.DeleteObject(packageProduct);

and assuming this isn't due to inlining of DeleteObject (i.e. the error actually being inside there) then there are only two possible causes of a NullReferenceException:

并假设这不是由于内联DeleteObject(即错误实际存在于那里),那么NullReferenceException只有两个可能的原因:

  • _entities being null
  • _entities为null

  • _entities.PackageProducts being null
  • _entities.PackageProducts为null

If this happens reproducibly, it should be easy to find out which it is:

如果这种情况可重复发生,应该很容易找出它是什么:

public void Delete(PackageProduct packageProduct)
{
    var x = _entities;
    if (x == null)
    {
        throw new Exception("_entities was null");
    }
    var y = x.PackageProducts;
    if (y == null)
    {
        throw new Exception("_entities.PackageProducts was null");
    }
    y.DeleteObject(packageProduct);
}

(Just for the purposes of diagnosis, of course.)

(当然,仅用于诊断目的。)

#2


2  

I've figured it out - thanks for everyone's time. The stack trace revealed I was looking at the wrong exception:

我已经明白了 - 谢谢大家的时间。堆栈跟踪显示我正在查看错误的异常:

Line 618: var result = new { Message = ex.Message, InnerException = ex.InnerException.ToString() };

第618行:var result = new {Message = ex.Message,InnerException = ex.InnerException.ToString()};

the null reference was coming from the InnerException being null. The real exception was:

null引用来自InnerException为null。真正的例外是:

base {System.SystemException} = {"The object cannot be deleted because it was not found in the ObjectStateManager."}

Which was solved by changing how I got the list of packageProducts, originally like this:

通过改变我获得packageProducts列表的方式解决了这个问题,最初是这样的:

 IPackageRepository packageRepository = new PackageRepository();
 var package = packageRepository.GetPackage(id);

 IPackageProductRepository packageProductRepository = new PackageProductRepository();
 var packageProducts = package.PackageProducts.ToList();

And this is how it is now:

这就是现在的情况:

 IPackageProductRepository packageProductRepository = new PackageProductRepository();
 var packageProducts = packageProductRepository.GetPackageProducts().Where(p=>p.PackageId == package.PackageId).ToList();

And it's working!

而且它正在工作!

But thanks for everything - I learned some new tricks for debugging :D!

但是感谢一切 - 我学会了一些新的调试技巧:D!

#3


2  

What can sometimes happen is that the exception happens, then is caught and rethrown, which can mess up the stack trace and make it hard to find.

有时可能发生的是异常发生,然后被捕获并重新抛出,这可能会弄乱堆栈跟踪并使其难以找到。

These are almost always solved easily by changing the debugger "break on exception" settings.

通过更改调试器“break on exception”设置,几乎总能轻松解决这些问题。

Instructions:

  1. From Visual Studio, Look for the Debug menu, and select Exceptions
  2. 从Visual Studio中,查找“调试”菜单,然后选择“例外”

  3. Expand the Common Language Runtime Exceptions tree-node, expand System and check System.NullReferenceException
  4. 展开Common Language Runtime Exceptions树节点,展开System并检查System.NullReferenceException

  5. Click OK to close and save
  6. 单击“确定”关闭并保存

  7. Re-run the code which causes the problem
  8. 重新运行导致问题的代码

The debugger should now break on the line of code where the exception is thrown, not where it is caught, and you should now be able to figure it out :-)

调试器现在应该在引发异常的代码行上中断,而不是在它被捕获的地方,你现在应该能够弄清楚:-)

PS: Rather than ticking specific exceptions, I'll often just tick the root node to break on all CLR exceptions. You'll probably get some a false positives when your app starts up, but if you're not sure what the root cause of something is, it definitely helps

PS:我通常只是勾选根节点来打破所有CLR异常,而不是勾选特定的异常。当你的应用程序启动时,你可能会得到一些误报,但是如果你不确定某些东西是什么原因,那肯定有帮助

#4


2  

Here's another problem that causes the same error when you deploy to your IIS Server, I hope it helps someone:

这是在部署到IIS服务器时导致相同错误的另一个问题,我希望它可以帮助某人:

In IIS, in the app pool, I had bumped up my "Maximum Worker Processes" to 3. This causes serious issues with the ASP.NET Session state, and causes the session to go in and out since it's being shared across the 3 workers.

在IIS中,在应用程序池中,我将“最大工作进程数”提升到3.这会导致ASP.NET会话状态出现严重问题,并导致会话进出,因为它在3个工作程序之间共享。

Just set it to 1 and your problem will be fixed.

只需将其设置为1即可解决您的问题。

In IIS, go to "Application Pools", and click on the one that your site is under. Then click on Advanced Settings. Set "Maximum Worker Processes to 1, and click Save. I hope this helps someone searching for a solution.

在IIS中,转到“应用程序池”,然后单击您的站点所在的那个。然后单击“高级设置”。将“Maximum Worker Processes”设置为1,然后单击“Save”。我希望这可以帮助搜索解决方案的人。

#1


5  

Well, if it's making it as far as this line:

好吧,如果它正在这条线上:

_entities.PackageProducts.DeleteObject(packageProduct);

and assuming this isn't due to inlining of DeleteObject (i.e. the error actually being inside there) then there are only two possible causes of a NullReferenceException:

并假设这不是由于内联DeleteObject(即错误实际存在于那里),那么NullReferenceException只有两个可能的原因:

  • _entities being null
  • _entities为null

  • _entities.PackageProducts being null
  • _entities.PackageProducts为null

If this happens reproducibly, it should be easy to find out which it is:

如果这种情况可重复发生,应该很容易找出它是什么:

public void Delete(PackageProduct packageProduct)
{
    var x = _entities;
    if (x == null)
    {
        throw new Exception("_entities was null");
    }
    var y = x.PackageProducts;
    if (y == null)
    {
        throw new Exception("_entities.PackageProducts was null");
    }
    y.DeleteObject(packageProduct);
}

(Just for the purposes of diagnosis, of course.)

(当然,仅用于诊断目的。)

#2


2  

I've figured it out - thanks for everyone's time. The stack trace revealed I was looking at the wrong exception:

我已经明白了 - 谢谢大家的时间。堆栈跟踪显示我正在查看错误的异常:

Line 618: var result = new { Message = ex.Message, InnerException = ex.InnerException.ToString() };

第618行:var result = new {Message = ex.Message,InnerException = ex.InnerException.ToString()};

the null reference was coming from the InnerException being null. The real exception was:

null引用来自InnerException为null。真正的例外是:

base {System.SystemException} = {"The object cannot be deleted because it was not found in the ObjectStateManager."}

Which was solved by changing how I got the list of packageProducts, originally like this:

通过改变我获得packageProducts列表的方式解决了这个问题,最初是这样的:

 IPackageRepository packageRepository = new PackageRepository();
 var package = packageRepository.GetPackage(id);

 IPackageProductRepository packageProductRepository = new PackageProductRepository();
 var packageProducts = package.PackageProducts.ToList();

And this is how it is now:

这就是现在的情况:

 IPackageProductRepository packageProductRepository = new PackageProductRepository();
 var packageProducts = packageProductRepository.GetPackageProducts().Where(p=>p.PackageId == package.PackageId).ToList();

And it's working!

而且它正在工作!

But thanks for everything - I learned some new tricks for debugging :D!

但是感谢一切 - 我学会了一些新的调试技巧:D!

#3


2  

What can sometimes happen is that the exception happens, then is caught and rethrown, which can mess up the stack trace and make it hard to find.

有时可能发生的是异常发生,然后被捕获并重新抛出,这可能会弄乱堆栈跟踪并使其难以找到。

These are almost always solved easily by changing the debugger "break on exception" settings.

通过更改调试器“break on exception”设置,几乎总能轻松解决这些问题。

Instructions:

  1. From Visual Studio, Look for the Debug menu, and select Exceptions
  2. 从Visual Studio中,查找“调试”菜单,然后选择“例外”

  3. Expand the Common Language Runtime Exceptions tree-node, expand System and check System.NullReferenceException
  4. 展开Common Language Runtime Exceptions树节点,展开System并检查System.NullReferenceException

  5. Click OK to close and save
  6. 单击“确定”关闭并保存

  7. Re-run the code which causes the problem
  8. 重新运行导致问题的代码

The debugger should now break on the line of code where the exception is thrown, not where it is caught, and you should now be able to figure it out :-)

调试器现在应该在引发异常的代码行上中断,而不是在它被捕获的地方,你现在应该能够弄清楚:-)

PS: Rather than ticking specific exceptions, I'll often just tick the root node to break on all CLR exceptions. You'll probably get some a false positives when your app starts up, but if you're not sure what the root cause of something is, it definitely helps

PS:我通常只是勾选根节点来打破所有CLR异常,而不是勾选特定的异常。当你的应用程序启动时,你可能会得到一些误报,但是如果你不确定某些东西是什么原因,那肯定有帮助

#4


2  

Here's another problem that causes the same error when you deploy to your IIS Server, I hope it helps someone:

这是在部署到IIS服务器时导致相同错误的另一个问题,我希望它可以帮助某人:

In IIS, in the app pool, I had bumped up my "Maximum Worker Processes" to 3. This causes serious issues with the ASP.NET Session state, and causes the session to go in and out since it's being shared across the 3 workers.

在IIS中,在应用程序池中,我将“最大工作进程数”提升到3.这会导致ASP.NET会话状态出现严重问题,并导致会话进出,因为它在3个工作程序之间共享。

Just set it to 1 and your problem will be fixed.

只需将其设置为1即可解决您的问题。

In IIS, go to "Application Pools", and click on the one that your site is under. Then click on Advanced Settings. Set "Maximum Worker Processes to 1, and click Save. I hope this helps someone searching for a solution.

在IIS中,转到“应用程序池”,然后单击您的站点所在的那个。然后单击“高级设置”。将“Maximum Worker Processes”设置为1,然后单击“Save”。我希望这可以帮助搜索解决方案的人。