I have a property on my BaseController called DataContext that holds my LINQ to SQL data context (or fake context for testing). When using a parameterless constructor (in other words, when a request to ASP.NET MVC is made), a new instance of my LINQ to SQL data context is assigned to the property:
public class BaseController : Controller {
public IDataContextWrapper DataContext { get; set; }
public BaseController() : this(new DataContextWrapper<MyDataContext>()) { }
public BaseController(IDataContextWrapper context) {
DataContext = context;
}
}
Also in my BaseController, I set some global ViewData items:
protected override void OnActionExecuting(ActionExecutingContext filterContext) {
ViewData["Example"] = DataContext.Table<Example>().Count();
base.OnActionExecuting(filterContext);
}
This is working fine for almost every action. The only one that doesn’t work is the Logout action on my AccountController:
public ActionResult Logout() {
FormsAuth.SignOut();
return RedirectToResult("Login");
}
This raises a NullReferenceException during BaseController.OnActionExecuting. When executing that particular action, the DataContext property is null.
Why would this only occur on one action?
Note: IDataContextWrapper and DataContextWrapper simply wraps the existing functionality of the LINQ to SQL DataContext object so that it can be replaced with a fake context in unit tests. It doesn’t do any disposing on its own, but leaves it up to the underlying DataContext, so I’m pretty certain that’s not the problem.
For reasons that I don’t quite understand, when a new AccountController is created for the Logout action, ASP.NET MVC is using the second constructor with a null parameter (could be a bug?). I changed the class to create a new default DataContext when the parameter is null:
Now it works.
It strikes me as strange that ASP.NET MVC used the default constructor in some cases, and an overload in others, though. Can anyone shed some light on this?