最近需要在Quartz一个定时器中没隔段时间执行一个操作,在这个过程当中需要获取到 ApplicationUserManager 对象。因为原来这些对象是在控制器中定义的,为了使用,特意把其挪到了定时任务操作类中。
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? httpContextBase.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
/// <summary>
/// 在controller.httpcontext为null时使用
/// </summary>
HttpContextBase httpContextBase
{
get
{
HttpContextWrapper context =
new HttpContextWrapper(System.Web.HttpContext.Current);
return (HttpContextBase)context;
}
}
定时器中的使用语句:
var operatorModel = UserManager.Users.FirstOrDefault(m => m.IID == item.AdminId);
错误日志中爆出了这样的错误:
值不能为 null。
参数名: httpContext<
指向的语句是:new HttpContextWrapper(System.Web.HttpContext.Current);
这个错误原因是HttpContext.Current 是在web线程中才起作用。为什么可以在controller 所有地方可以用,因为整个 web 应用都是一个线程。而定时任务是新创建了一个线程,与web 线程不是一个,因此 HttpContext.Current 是 null。
但是在网上搜索的,并没有好的解决办法。唯一一个说可以解决的,说是把 httpcontext.current 存到一个缓存中,然后在线程中使用。但是我看了写法,代码太多,感觉处理的好复杂,不想用。结合本次问题是有关ASP.NET Identity V2 的使用的。觉得我可以使用我刚刚发过的上篇文章
ApplicationUserManager对象的两种创建方法
觉得可以使用这两种创建方法的第二种解决此问题。解决代码如下:
private LMIdentityDbContext _db = new IdentityDbContext();
protected ApplicationUserManager userManager
{
get
{
var store = new UserStore<ApplicationUser>(_db);
return _userManager ?? new ApplicationUserManager(store);
}
private set
{
_userManager = value;
}
}
使用方法:
var operatorModel = userManager.Users.FirstOrDefault(m => m.IID == item.AdminId);
这次经过测试,没有问题了