Grahame A
Grahame A

Reputation: 3953

Object Reference not set to instance of an object...but it is?

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.

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);
            }
        }

Upvotes: 7

Views: 37721

Answers (4)

Paul D
Paul D

Reputation: 676

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

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.

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

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.

Upvotes: 2

Orion Edwards
Orion Edwards

Reputation: 123622

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.

Instructions:

  1. From Visual Studio, Look for the Debug menu, and select Exceptions
  2. Expand the Common Language Runtime Exceptions tree-node, expand System and check System.NullReferenceException
  3. Click OK to close and save
  4. Re-run the code which causes the problem

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

Upvotes: 2

Grahame A
Grahame A

Reputation: 3953

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() };

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

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:

 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!

Upvotes: 2

Jon Skeet
Jon Skeet

Reputation: 1499780

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:

  • _entities being null
  • _entities.PackageProducts being 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.)

Upvotes: 5

Related Questions