Reputation: 691
I try to make custom error handling (http://perspectivespace.com/100497697) with error module(Application_Error), HttpModuleMagic.MVC3, Ninject.MVC3, EF 4.1. Unfortunately when I want to log the error into the database it gives this error message: "The operation cannot be completed because the DbContext has been disposed."
Could somebody help me, please?
public class ErrorHandlerHttpModule : IHttpModule
{
private const string ErrorControllerRouteName = "Error";
private IErrorRepository errorRepo;
private IUserRepository userRepo;
// private IUserRepository UserRepository;
public ErrorHandlerHttpModule(IErrorRepository er, IUserRepository ur)
{
errorRepo = er;
userRepo = ur;
}
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.Error += Application_Error;
}
private void Application_Error(object sender, EventArgs e)
{
// Get the last error.
var exception = HttpContext.Current.Server.GetLastError();
...
error.User = userRepo.GetUserByName(name);
...
In the NinjectWebCommon.cs:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IErrorRepository>().To<ErrorRepository>().InRequestScope();
kernel.Bind<IUserRepository>().To<UserRepository>().InRequestScope();
kernel.Bind<IDatabaseFactory>().To<DatabaseFactory>().InRequestScope();
kernel.Bind<IDisposable>().To<Disposable>().InRequestScope();
kernel.Bind<IHttpModule>().To<ErrorHandlerHttpModule>();
}
... and the UserRepository class:
public class UserRepository : RepositoryBase<User>, IUserRepository
{
public UserRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
public User GetUserByName(string name)
{
User us = null;
try
{
us = dataContext.Users.Where(u => u.UserName.Equals(name)).FirstOrDefault() as User;
}
catch (Exception ex)
{
}
return us;
}
}
The RepositoryBase:
public abstract class RepositoryBase<T> where T : class
{
protected TestContext dataContext;
private readonly IDbSet<T> dbset;
protected RepositoryBase(IDatabaseFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
dbset = DataContext.Set<T>();
}
protected IDatabaseFactory DatabaseFactory
{
get;
private set;
}
protected TestContext DataContext
{
get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
}
...
and DatabaseFactory class:
public class DatabaseFactory : Disposable, IDatabaseFactory
{
private TestContext dataContext;
public TestContext Get()
{
return dataContext ?? (dataContext = new TestContext());
}
protected override void DisposeCore()
{
if (dataContext != null)
dataContext.Dispose();
}
}
This line dives the error:
dataContext.Users.Where(u => u.UserName.Equals(name)).FirstOrDefault() as User;
I try to follow this article: http://weblogs.asp.net/shijuvarghese/archive/2011/01/06/developing-web-apps-using-asp-net-mvc-3-razor-and-ef-code-first-part-1.aspx
Thank you for your answer.
Upvotes: 2
Views: 5879
Reputation: 97
The reason for this is that your LINQ query is deferred, in other words it is not run in your "UserRepository" but only in the calling code. So the DBContext has already been disposed of when it is executed. You can force it to execute immediately by changing
us = dataContext.Users.Where(u => u.UserName.Equals(name)).FirstOrDefault() as User
to
us = dataContext.Users.Where(u => u.UserName.Equals(name)).ToList().FirstOrDefault() as User
Upvotes: -1
Reputation:
protected override void DisposeCore()
{
if (dataContext != null)
{
dataContext.Dispose();
dataContext = null;
}
}
Upvotes: 3