Hangfire中以DirectoryEntry创建DirectorySearcher时触发NullReferenceException
问题:Hangfire工作进程中使用DirectoryEntry创建DirectorySearcher时抛出NullReferenceException
问题概述
在独立.NET 6控制台应用中可正常运行的AD查询逻辑,放到Hangfire Server工作进程(Windows服务托管)中执行时,在new DirectorySearcher(dirEntry)或dirSearcher.SearchRoot = dirEntry处抛出System.NullReferenceException。但在即时窗口中用同一个dirEntry实例创建DirectorySearcher却能正常执行。
触发异常的核心代码
实现IADConnector接口的LocalADConnector类关键方法:
public class LocalADConnector : IADConnector { public void GetUserADInfo(string username, string saGUID) { if (string.IsNullOrWhiteSpace(username)) { throw new ArgumentNullException(nameof(username), $"Argument {nameof(username)} of type {username.GetType()} may not be null or empty."); } using (DirectoryEntry dirEntry = new DirectoryEntry(_adServer, _adUser, _adPass)) { using (DirectorySearcher dirSearcher = new DirectorySearcher(dirEntry)) // 异常触发点 { dirSearcher.Filter = $"(&(objectClass=user)(SAMAccountName={username}))"; using (DirectoryEntry adUser = dirSearcher.FindOne().GetDirectoryEntry()) { if (adUser == null) { throw new ArgumentException($"User with the username {username} does not exist!"); } foreach (string property in adUser.Properties.PropertyNames) { Console.WriteLine($"{property}: {adUser.Properties[property].Value}"); } } } } } }
Hangfire队列调用代码
通过Web项目将任务加入队列,由Windows服务托管的Hangfire Server执行:
public void UpdateUser(string employeeID, IHRConnector hrConnector, IADConnector adConnector, string saGUID) { try { adConnector.GetUserADInfo(employeeID, saGUID); // 其他无关业务逻辑 } catch (Exception ex) { Log.Error(ex); throw; } }
Hangfire序列化配置
builder.Services.AddHangfire(config => config.SetDataCompatibilityLevel(CompatibilityLevel.Version_170) .UseSimpleAssemblyNameTypeSerializer() .UseDefaultTypeSerializer() .UseSerializerSettings(new Newtonsoft.Json.JsonSerializerSettings { TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto }) .UseSqlServerStorage($"{builder.Configuration.GetConnectionString("HangfireDB")}uid={Environment.GetEnvironmentVariable("LGN_HF_USR", EnvironmentVariableTarget.Machine)};pwd={Environment.GetEnvironmentVariable("LGN_HF_PWD", EnvironmentVariableTarget.Machine)}", new Hangfire.SqlServer.SqlServerStorageOptions { SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5) }) );
排查过程
- 尝试先创建空DirectorySearcher再设置
SearchRoot属性,异常仍在dirSearcher.SearchRoot = dirEntry处触发 - 即时窗口中使用同一个
dirEntry实例创建DirectorySearcher,操作完全正常 - 后续排查发现:创建默认DirectorySearcher时,NullReferenceException出现在其他日志行,怀疑当前方法所在对象被提前清理或设为null
- 最终确认:问题根源是Hangfire入队方法的参数包含接口类型(
IHRConnector、IADConnector)
内容的提问来源于stack exchange,提问作者Correllion115
相关产品推荐
相关产品推荐

