请考虑我拥有的Active Directory服务中的以下代码段。在Rename()
方法中,它始终抛出ObjectDisposedException
,“无法访问已处置的对象。对象名称:'DirectoryEntry'。”
这曾经工作正常,但我也有一个Add()
方法,两者的代码是95%相同。所以,我选择了SetIdentity()
方法,我将传递主体和属性字典并从那里开始。 Add()
方法有效,但那是因为还没有底层对象可以操作。 Rename()
方法失败,因为有一个。
我知道如果我将SetIdentity()
的代码放回Rename()
,它会正常工作,但我不想这样做。
我已尝试在using
块中Rename()
中包装try/catch
子句,但它没有做任何事情。我试过通过ref
传递校长和字典,但这也没有帮助。我已经尝试检查DirectoryEntry
是否为空,但没有帮助。
所以,我猜它不能是using
子句中失败的代码。我还应该寻找什么?
使用Visual Studio进行调试时,我可以将鼠标悬停在对象上,它就在那里并完成了属性和值,所以我不知道我应该在哪里看...
public override void Rename(
UserPrincipal principal,
IDictionary<string, object> properties) {
if (principal != null) {
this.SetIdentity(ref principal, ref properties);
using (DirectoryEntry entry = (principal.GetUnderlyingObject() as DirectoryEntry)) {
entry.Rename(newName: String.Format("CN={0}", principal.DisplayName));
entry.CommitChanges();
};
principal.Save(); // this is where ASP.NET runtime points to when failed
};
} // this is where Visual Studio points to when debugging
internal void SetIdentity(
ref UserPrincipal principal,
ref IDictionary<string, object> properties) {
object obj = null;
string displayName = string.Empty;
string givenName = string.Empty;
string middleName = string.Empty;
string samAccountName = string.Empty;
string surname = string.Empty;
if (properties.TryGetValue("GivenName", out obj)) {
givenName = (string)properties["GivenName"];
};
if (properties.TryGetValue("MiddleName", out obj)) {
middleName = (string)properties["MiddleName"];
};
if (properties.TryGetValue("Surname", out obj)) {
surname = (string)properties["Surname"];
};
if (properties.TryGetValue("SamAccountName", out obj)) {
samAccountName = (string)properties["SamAccountName"];
};
if (String.IsNullOrEmpty(middleName)) {
displayName = String.Format("{0} {1}", givenName, surname);
if (String.IsNullOrEmpty(samAccountName)) {
samAccountName = String.Format("{0}{1}", givenName[0], surname);
};
} else {
displayName = String.Format("{0} {1}. {2}", givenName, middleName[0], surname);
if (String.IsNullOrEmpty(samAccountName)) {
samAccountName = String.Format("{0}{1}{2}", givenName[0], middleName[0], surname);
};
};
samAccountName = samAccountName.ToLower();
principal.DisplayName = displayName;
principal.GivenName = givenName;
principal.MiddleName = middleName;
principal.SamAccountName = samAccountName;
principal.Surname = surname;
principal.UserPrincipalName = String.Format("{0}@dryforce.com", samAccountName);
}
答案 0 :(得分:6)
using (DirectoryEntry entry = (principal.GetUnderlyingObject() as DirectoryEntry))
为.NET设计师购买一支雪茄,以获得良好的方法命名。您正在使用using语句处理“底层对象”。你猛地踩下地板垫,使得班级工作的对象不复存在。这是一只死鹦鹉。相当于处理StreamReader.BaseStream。在你这样做之后试图从它上面读取Kaboom,无法从被处置的底层物体中读取。
处理它不是你的工作,你的代码没有创建它。通过省略 using 关键字来解决问题。