Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 尝试从Active Directory检索和设置OU,然后使用C中的目录项在OU上设置新属性#_C#_Active Directory_Directoryservices - Fatal编程技术网

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

C# 尝试从Active Directory检索和设置OU,然后使用C中的目录项在OU上设置新属性#,c#,active-directory,directoryservices,C#,Active Directory,Directoryservices,此方法尝试获取中心OU下的所有OU目录,一次一个,与我的中心对象列表中的名称匹配 接下来,它会尝试为每个属性设置一对属性(以前未创建过的属性) 它获取OU,转到.Add分支并崩溃。我误解了什么 我得到“未指定错误\n\n”异常,调用堆栈如下 位于System.DirectoryServices.Interop.UnsafentiveMethods.IAds.PutEx(Int32 lnControlCode、字符串bstrName、对象vProp) 位于System.DirectoryServi

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

接下来,它会尝试为每个属性设置一对属性(以前未创建过的属性)

它获取OU,转到.Add分支并崩溃。我误解了什么

我得到“未指定错误\n\n”异常,调用堆栈如下

位于System.DirectoryServices.Interop.UnsafentiveMethods.IAds.PutEx(Int32 lnControlCode、字符串bstrName、对象vProp) 位于System.DirectoryServices.PropertyValueCollection.OnInsertComplete(Int32索引,对象值) 位于System.Collections.CollectionBase.System.Collections.IList.Add(对象值) 位于System.DirectoryServices.PropertyValueCollection.Add(对象值) 在StudentPortalDevFixTool.Form1.button输入\单击D:\TFS\StudentPortalDevFixTool\StudentPortalDevFixTool\Form1.cs:第599行中的(对象发送者,事件参数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.ctrid
null
或者它无法处理的某种奇怪类型。但是异常的错误消息将确认这一点,如果您可以共享它的话

但还有一些评论:

Mysearcher.SearchScope = SearchScope.Subtree;
Subtree
是默认值,因此如果需要设置,则无需进行设置

centerDe.Properties[ "UserPropertyCache" ].Value = true;
UserPropertyCache
不是广告属性。我认为您正在尝试使用
DirectoryEntry
的(注意,无“r”)属性,在这种情况下,您可以这样做:

centerDe.UsePropertyCache = true;
但是
true
是默认值,所以您不需要这样做

那么这个,

centerDe.RefreshCache();
调用
RefreshCache()
告诉它转到AD并检索对象的每个属性。当您第一次使用
Properties
读取属性,而该属性尚未在缓存中时,也会发生同样的情况。通过执行以下操作,您可以告诉它仅检索实际要查看的属性:

centerDe.RefreshCache(new [] { "telexNumber", "centerCode" });
这将告诉它只检索这两个属性

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

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

还有这个:

catch ( Exception ex )
{
    throw;
}
这有什么原因吗?事实上,如果您只想重新播放try/catch块,那么使用try/catch块是毫无意义的

您还可以使用该语句稍微简化代码

以下是您的代码以及我的所有建议:

private void按钮输入\u单击(对象发送者,事件参数e)
{
字符串adConnStr=ConfigurationSettings.AppSettings[“DeUrl”];
字符串adServerUser=ConfigurationSettings.AppSettings[“DeAcct”];
字符串adServerPassword=ConfigurationSettings.AppSettings[“DePwd”];
字符串adServerContainer=ConfigurationSettings.AppSettings[“AD_DomainOu”];
//看起来像这样:“DC=AD,DC=MyDomain,DC=org”
如果(!string.IsNullOrEmpty(adConnStr)和&!string.IsNullOrEmpty(adServerUser)和&!string.IsNullOrEmpty(adServerPassword)和&!string.IsNullOrEmpty(adServerContainer))
{
字符串adName=textBox\u adName\u unlock.Text;
尝试
{
DirectoryEntry startSearch=新的DirectoryEntry(adConnStr、adServerUser、adServerPassword);
foreach(中心列表中的中心中心中心来自CDSS)
{
我的搜索者;
if(startSearch==null)
{
抛出新异常(“BuildDirectoryEntry中没有根(…)”;
}
Mysearcher=新的目录搜索器(startSearch);
mysearch.Filter=“(&(objectCategory=organizationalUnit)(ou=“+ctr.shname+”)”;
SearchResult=Mysearcher.FindOne();
如果(结果==null)继续;
DirectoryEntry centerDe=result.GetDirectoryEntry();
centerDe.Properties[“电传号码”].Add(ctr.ctrid.ToString());
centerDe.Properties[“centerCode”].Add(ctr.ctrCode.ToString());
centerDe.CommitChanges();
centerDe.Close();
}
}
捕获(例外情况除外)
{
Show(“异常:+ex.ToString());
}
}
}

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

ctrid=2刷新缓存的内容,谢谢,我是从另一个线程上的评论中得到的,现在我明白发生了什么。捕获并重新抛出一个异常,这样我就可以在抛出异常的方法中放置一个断点。这纯粹是为了调试。在一个不那么普通的应用程序*(这是一个一次性工具)中,我也会把它记录在那里。我更新了它以显示异常消息,可能是在您键入此答案时。我收到“Unspecified error\n\n”异常,调用堆栈位于原始消息中,因为消息没有太大帮助。谢谢因此,该值为
2
。在我做的小测试中,我猜它不是
int
。因为如果我做了
.Add(2)
,它工作得很好。但是如果我执行
.Add(2d)
(强制它使用
十进制
类型),那么它将失败,并出现相同的错误。只需对其调用
.ToString()
。我更新了我的答案。我添加了.ToString()(因为它是Int64)并现在设置,但当我提交更改时,我得到“指定的目录服务属性或值不存在”。我如何添加新的不存在的设置,如CenterCode?这将需要修改您的AD计划