UserPrincipal.Save()导致ObjectDisposedException

Gup*_*R4c 1 .net c# active-directory

请考虑我拥有的Active Directory服务中的以下代码段.在该Rename()方法中,它始终抛出ObjectDisposedException" 无法访问已处置的对象.对象名称:'DirectoryEntry'. "

这曾经工作得很好,但我也有一个Add()方法,两个是95%完全相同的代码.所以,我选择了SetIdentity()传递主体和属性字典的方法并从那里开始.该Add()方法有效,但那是因为还没有底层对象可以操作.该Rename()方法失败,因为有一个.

我知道,如果我把代码放SetIdentity()回去,Rename()它会工作得很好,但我不想这样做.

我已经尝试在一个块中包装该using子句,但它没有做任何事情.我试过传递校长和字典,但这也没有帮助.我已经尝试检查是否为null并且它没有帮助.Rename()try/catchrefDirectoryEntry

所以,我猜它不能是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);
}
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 6

   using (DirectoryEntry entry = (principal.GetUnderlyingObject() as DirectoryEntry))
Run Code Online (Sandbox Code Playgroud)

为.NET设计师购买一支雪茄,以获得良好的方法命名.您正在使用using语句处理"底层对象".你猛地踩下地板垫,使得班级工作的对象不复存在.这是一只死鹦鹉.相当于处理StreamReader.BaseStream.在你这样做之后试图从它上面读取Kaboom,无法从被处置的底层对象中读取.

处理它不是你的工作,你的代码没有创建它.通过省略using关键字来解决问题.