Reputation: 3953
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
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
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:
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
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
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 nullIf 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