You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 14:02:35