英文:
Hangfire - Creating a new DirectorySearcher object with a DirectoryEntry as an argument throws NullReferenceException
问题
I am trying to create a DirectorySearcher
object using an existing DirectoryEntry
object, but when I do it throws a System.NullReferenceException
on that line. The following works in a standalone .NET 6.0 Console application, but not in a .Net 6.0 Console application that is doing work as a worker for a Hangfire Server. Here is the class and method that I get the exception with:
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)) //Exception is thrown here.
{
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}");
}
}
}
}
}
}
Here is the method that will get enqueued by Hangfire through the web project, and then executed by a Windows service:
public void UpdateUser(string employeeID, IHRConnector hrConnector, IADConnector adConnector, string saGUID)
{
try
{
adConnector.GetUserADInfo(employeeID, saGUID);
//There is other stuff here, but it's not relevant.
}
catch (Exception ex)
{
Log.Error(ex);
throw;
}
}
And here is the serialization settings for 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) })
);
I have tried creating the objects and then applying the properties after, but the exception occurs at the
dirSearcher.SearchRoot = dirEntry;
line. Creating a DirectorySearcher
object in the immediate window using dirEntry
works just fine.
Thanks in advance.
UPDATE:
The NullReferenceException
occurred on a different logging line when I tried creating a default DirectorySearcher
, so I think the actual object that this method is in is getting cleaned up/set to null for some reason.
UPDATE 2:
I'm convinced this issue is coming from having an interface as one of the arguments for the method enqueued by Hangfire. I have updated the code above to show more of the problem.
英文:
I am trying to create a DirectorySearcher
object using an existing DirectoryEntry
object, but when I do it throws a System.NullReferenceException
on that line. The following works in a standalone .NET 6.0 Console application, but not in a .Net 6.0 Console application that is doing work as a worker for a Hangfire Server. Here is the class and method that I get the exception with:
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)) //Exception is thrown here.
{
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}");
}
}
}
}
}
}
Here is the method that will get enqueued by Hangfire through the web project, and then executed by a Windows service:
public void UpdateUser(string employeeID, IHRConnector hrConnector, IADConnector adConnector, string saGUID)
{
try
{
adConnector.GetUserADInfo(employeeID, saGUID);
//There is other stuff here, but it's not relevant.
}
catch (Exception ex)
{
Log.Error(ex);
throw;
}
}
And here is the serialization settings for 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) })
);
I have tried creating the objects and then applying the properties after, but the exception occurs at the
dirSearcher.SearchRoot = dirEntry;
line. Creating a DirectorySearcher
object in the immediate window using dirEntry
works just fine.
Thanks in advance.
UPDATE:
The NullReferenceException
occurred on a different logging line when I tried creating a default DirectorySearcher
, so I think the actual object that this method is in is getting cleaned up/set to null for some reason.
UPDATE 2:
I'm convinced this issue is coming from having an interface as one of the arguments for the method enqueued by Hangfire. I have updated the code above to show more of the problem.
答案1
得分: 0
这有点尴尬,但问题在于我在Release模式下调试,而不是Debug模式,所以它没有给我正确的System.NullReferenceException
发生的代码行。具体来说,异常是因为尝试获取一个不存在的AD属性的值而引发的。感谢所有人的帮助,以及Bing Chat指引我走向正确的方向。
英文:
This is embarrassing, but the issue was that I was debugging in Release and not Debug, so it wasn't giving me the correct line that the System.NullReferenceException
was happening on. Specifically, the exception was from trying to get the value of an AD property that didn't exist. Thanks for everyone's help, and Bing Chat for pointing me in the right direction.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论