尝试从Active Directory检索和OU,然后使用C#中的目录项在OU上设置新属性



此方法尝试获取Center OU下的所有OU目录,每次一个,与我的Center对象列表中的名称匹配。

接下来,它尝试为每个属性设置一对属性(以前没有创建过(

它得到OU,转到。添加分支和崩溃。我误解了什么。

我得到了"未指定错误"的异常,下面是调用堆栈

在系统中。目录服务。Interop。UnsafeNativeMethods。IAds。PutEx(Int32 lnControlCode,字符串bstrName,对象vDrop(在系统中。目录服务。PropertyValueCollection。OnInsertComplete(Int32索引,对象值(在系统中。集合。CollectionBase。系统集合。IList。Add(对象值(在系统中。目录服务。PropertyValueCollection。Add(对象值(StudentPortalDevFixTool。D:\TFS\StudentPortalDevFixTool\StudentPortal DevFixTool\Form1.cs:line 599 中的Form1.buttonfixCenters_Click(对象发送器,EventArgs e(

我以前也这样做过,但就像8年前一样。谢谢

private void buttonfixCenters_Click( object sender, EventArgs e )
{
string adConnStr = ConfigurationSettings.AppSettings["DeUrl"];
string adServerUser = ConfigurationSettings.AppSettings["DeAcct"];
string adServerPassword = ConfigurationSettings.AppSettings["DePwd"];
string adServerContainer = ConfigurationSettings.AppSettings["AD_DomainOu"];
// looks like this: "DC=AD,DC=MyDomain,DC=org"
if( !string.IsNullOrEmpty( adConnStr ) && !string.IsNullOrEmpty(adServerUser) && !string.IsNullOrEmpty(adServerPassword) && !string.IsNullOrEmpty(adServerContainer) )
{
string adName = textBox_adname_unlock.Text;
try
{
DirectoryEntry startSearch = new DirectoryEntry( adConnStr, adServerUser, adServerPassword );
foreach ( Center ctr in CenterListFromCdss )
{
try
{
DirectorySearcher Mysearcher;
if ( startSearch == null )
{
throw new Exception( "No root in BuildDirectoryEntry(...)" );
}
Mysearcher = new DirectorySearcher( startSearch );
Mysearcher.SearchScope = SearchScope.Subtree;
Mysearcher.Filter = "(&(objectCategory=organizationalUnit)(ou=" + ctr.shname + "))";
SearchResult result = Mysearcher.FindOne();
DirectoryEntry centerDe;
if ( result == null)
{
centerDe = null;
}
else
{
centerDe  = result.GetDirectoryEntry();
}

if ( centerDe != null )
{
centerDe.Properties[ "UserPropertyCache" ].Value = true; 
centerDe.RefreshCache();
if ( result.Properties.Contains( "telexNumber" ) )
{
centerDe.Properties[ "telexNumber" ].Value = ctr.ctrid;
}
else
{
centerDe.Properties[ "telexNumber" ].Add( ctr.ctrid );// GOES BOOM HERE!
}
if ( result.Properties.Contains( "centerCode" ) )
{
centerDe.Properties[ "centerCode" ].Value = ctr.ctrCode;
}
else
{
centerDe.Properties[ "centerCode" ].Add( ctr.ctrCode );
}
//centerDe.Properties[ "telexNumber" ].Value = ctr.ctrid;
//centerDe.Properties[ "centerCode" ].Value = ctr.ctrCode;
centerDe.CommitChanges();
centerDe.Close();
}
}
catch ( Exception ex )
{
throw;
}
}
}
catch (Exception ex)
{
MessageBox.Show( "Exception: " + ex.ToString() );
}
}
}

我能猜测的唯一可能原因是ctr.ctridnull,或者是它无法处理的某种奇怪类型。但是,如果您可以共享,异常的错误消息将确认这一点。

但其他一些评论:

Mysearcher.SearchScope = SearchScope.Subtree;

Subtree是默认值,所以如果您想要的话,不需要设置它。

centerDe.Properties[ "UserPropertyCache" ].Value = true;

UserPropertyCache不是AD属性。我认为您正在尝试使用DirectoryEntryUsePropertyCache(注意,没有"r"(属性,在这种情况下,您会这样做:

centerDe.UsePropertyCache = true;

但是true是默认的,所以您不需要这么做。

然后这个:

centerDe.RefreshCache();

调用RefreshCache()告诉它去AD并检索对象的每个属性。当您第一次使用Properties读取属性,并且该属性还不在缓存中时,也会发生同样的情况。你可以告诉它只检索你真正想要查看的属性:

centerDe.RefreshCache(new [] { "telexNumber", "centerCode" });

这将告诉它只检索这两个属性。

然而,你甚至不需要这么做。你所做的只是增加一个新的价值,所以你并不真正关心已经存在的东西。

我看到你在.Value =.Add()之间切换,这取决于是否已经有一个值,但你不需要。你只需要使用.Add(),无论是否已经有值,它都会添加一个值。

然后是这样的:

catch ( Exception ex )
{
throw;
}

这是有原因的吗?事实上,如果你只想重新抛出try/catch块,那么它根本没有意义

您还可以使用continue语句来稍微简化您的代码。

这是你的代码,包括我的所有建议:

private void buttonfixCenters_Click( object sender, EventArgs e )
{
string adConnStr = ConfigurationSettings.AppSettings["DeUrl"];
string adServerUser = ConfigurationSettings.AppSettings["DeAcct"];
string adServerPassword = ConfigurationSettings.AppSettings["DePwd"];
string adServerContainer = ConfigurationSettings.AppSettings["AD_DomainOu"];
// looks like this: "DC=AD,DC=MyDomain,DC=org"
if( !string.IsNullOrEmpty( adConnStr ) && !string.IsNullOrEmpty(adServerUser) && !string.IsNullOrEmpty(adServerPassword) && !string.IsNullOrEmpty(adServerContainer) )
{
string adName = textBox_adname_unlock.Text;
try
{
DirectoryEntry startSearch = new DirectoryEntry( adConnStr, adServerUser, adServerPassword );
foreach ( Center ctr in CenterListFromCdss )
{
DirectorySearcher Mysearcher;
if ( startSearch == null )
{
throw new Exception( "No root in BuildDirectoryEntry(...)" );
}
Mysearcher = new DirectorySearcher( startSearch );
Mysearcher.Filter = "(&(objectCategory=organizationalUnit)(ou=" + ctr.shname + "))";
SearchResult result = Mysearcher.FindOne();
if ( result == null) continue;
DirectoryEntry centerDe  = result.GetDirectoryEntry();
centerDe.Properties[ "telexNumber" ].Add( ctr.ctrid.ToString() );
centerDe.Properties[ "centerCode" ].Add( ctr.ctrCode.ToString() );
centerDe.CommitChanges();
centerDe.Close();
}
}
catch (Exception ex)
{
MessageBox.Show( "Exception: " + ex.ToString() );
}
}
}

这可能仍然会在.Add( ctr.ctrid )上引发异常,但在我提供帮助之前,您必须共享错误消息。

最新更新