Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.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
在.NET中实现Active Directory更改通知_.net_Active Directory - Fatal编程技术网

在.NET中实现Active Directory更改通知

在.NET中实现Active Directory更改通知,.net,active-directory,.net,Active Directory,我正在尝试从active directory获取更改通知,以便在我的广告中出现任何更改时可以更新数据库中的数据。我搜索并找到了Ryan Dunn的一篇文章 我试着实现他的代码。应用程序启动时没有任何错误,但不会生成任何通知。有人能帮我吗 我的域名是win 2008服务器上的corp.am2k8vm.com,出于测试目的,我在active directory上几乎没有用户 using System; using System.Collections.Generic; using System.Di

我正在尝试从active directory获取更改通知,以便在我的广告中出现任何更改时可以更新数据库中的数据。我搜索并找到了Ryan Dunn的一篇文章

我试着实现他的代码。应用程序启动时没有任何错误,但不会生成任何通知。有人能帮我吗

我的域名是win 2008服务器上的
corp.am2k8vm.com
,出于测试目的,我在active directory上几乎没有用户

using System;
using System.Collections.Generic;
using System.DirectoryServices.Protocols;
using System.DirectoryServices;
namespace ChangeNotifications
{
    class Program
    {
        static void Main(string[] args)
        {
            using (LdapConnection connect = CreateConnection("192.168.182.209"))                //can also use localhost
            {
                using (ChangeNotifier notifier = new ChangeNotifier(connect))
                {
                    //register some objects for notifications (limit 5)
                    notifier.Register("dc=am2k8vm,dc=com", SearchScope.OneLevel);                     //not sure if the parameters are correct here as i am new to active directory stuff
                    notifier.Register("cn=Andy Main,ou=users,dc=am2k8vm,dc=com", SearchScope.Base); //not sure if the parameters are correct here as i am new to active directory stuff
                    notifier.ObjectChanged += new EventHandler<ObjectChangedEventArgs>(notifier_ObjectChanged);
                    Console.WriteLine("Waiting for changes...");
                    Console.WriteLine();
                    Console.ReadLine();
                }
            }
        }
        static void notifier_ObjectChanged(object sender, ObjectChangedEventArgs e)
        {
            Console.WriteLine(e.Result.DistinguishedName);
            foreach (string attrib in e.Result.Attributes.AttributeNames)
            {
                foreach (var item in e.Result.Attributes[attrib].GetValues(typeof(string)))
                {
                    Console.WriteLine("\t{0}: {1}", attrib, item);
                }
            }
            Console.WriteLine();
            Console.WriteLine("====================");
            Console.WriteLine();
        }
        static private LdapConnection CreateConnection(string server)
        {
            LdapConnection connect = new LdapConnection(server);
            connect.SessionOptions.ProtocolVersion = 3;
            connect.AuthType = AuthType.Negotiate;  //use my current credentials
            return connect;
        }
    }
    public class ChangeNotifier : IDisposable
    {
        LdapConnection _connection;
        HashSet<IAsyncResult> _results = new HashSet<IAsyncResult>();

        public ChangeNotifier(LdapConnection connection)
        {
            _connection = connection;
            _connection.AutoBind = true;
        }
        public void Register(string dn, SearchScope scope)
        {
            SearchRequest request = new SearchRequest(
                dn, //root the search here
                "(objectClass=*)", //very inclusive
                scope, //any scope works
                null //we are interested in all attributes
                );
            //register our search
            request.Controls.Add(new DirectoryNotificationControl());
            //we will send this async and register our callback
            //note how we would like to have partial results
            IAsyncResult result = _connection.BeginSendRequest(
                request,
                TimeSpan.FromDays(1), //set timeout to a day...
                PartialResultProcessing.ReturnPartialResultsAndNotifyCallback,
                Notify,
                request
                );
            //store the hash for disposal later
            _results.Add(result);
        }
        private void Notify(IAsyncResult result)
        {
            //since our search is long running, we don't want to use EndSendRequest
            PartialResultsCollection prc = _connection.GetPartialResults(result);
            foreach (SearchResultEntry entry in prc)
            {
                OnObjectChanged(new ObjectChangedEventArgs(entry));
            }
        }
        private void OnObjectChanged(ObjectChangedEventArgs args)
        {
            if (ObjectChanged != null)
            {
                ObjectChanged(this, args);
            }
        }
        public event EventHandler<ObjectChangedEventArgs> ObjectChanged;
        #region IDisposable Members
        public void Dispose()
        {
            foreach (var result in _results)
            {
                //end each async search
                _connection.Abort(result);
            }
        }
        #endregion
    }
    public class ObjectChangedEventArgs : EventArgs
    {
        public ObjectChangedEventArgs(SearchResultEntry entry)
        {
            Result = entry;
        }
        public SearchResultEntry Result { get; set;}
    }
}
使用系统;
使用System.Collections.Generic;
使用System.DirectoryServices.Protocols;
使用System.DirectoryServices;
命名空间更改通知
{
班级计划
{
静态void Main(字符串[]参数)
{
使用(LdapConnection connect=CreateConnection(“192.168.182.209”)//也可以使用localhost
{
使用(变更通知程序通知程序=新变更通知程序(连接))
{
//为通知注册某些对象(限制5)
notifier.Register(“dc=am2k8vm,dc=com”,SearchScope.OneLevel);//我不确定这里的参数是否正确,因为我是active directory新手
notifier.Register(“cn=Andy Main,ou=users,dc=am2k8vm,dc=com”,SearchScope.Base);//我不确定这里的参数是否正确,因为我是active directory新手
notifier.ObjectChanged+=新的事件处理程序(notifier\u ObjectChanged);
Console.WriteLine(“等待更改…”);
Console.WriteLine();
Console.ReadLine();
}
}
}
静态无效通知程序\u ObjectChanged(对象发送方,ObjectChangedEventArgs e)
{
Console.WriteLine(例如,Result.DifferentiedName);
foreach(e.Result.Attributes.AttributeName中的字符串attrib)
{
foreach(e.Result.Attributes[attrib].GetValues(typeof(string))中的var项)
{
WriteLine(“\t{0}:{1}”,attrib,item);
}
}
Console.WriteLine();
Console.WriteLine(“===============================”);
Console.WriteLine();
}
静态专用LdapConnection CreateConnection(字符串服务器)
{
LdapConnection connect=新的LdapConnection(服务器);
connect.SessionOptions.ProtocolVersion=3;
connect.AuthType=AuthType.Negotiate;//使用我当前的凭据
返回连接;
}
}
公共类更改通知程序:IDisposable
{
LdapConnection\u连接;
HashSet_results=新HashSet();
公共变更通知程序(LdapConnection连接)
{
_连接=连接;
_connection.AutoBind=true;
}
公共无效寄存器(字符串dn,搜索范围)
{
SearchRequest=新的SearchRequest(
dn,//在此处搜索根目录
“(objectClass=*)”,//非常包容
scope,//任何scope都有效
null//我们对所有属性都感兴趣
);
//注册我们的搜索
Add(newdirectorynotificationcontrol());
//我们将发送此异步并注册回调
//请注意,我们希望得到部分结果
IAsyncResult结果=\u connection.BeginSendRequest(
要求
TimeSpan.FromDays(1),//将超时设置为一天。。。
PartialResultProcessing.ReturnPartialResultsAndNotifyCallback,
通知
要求
);
//存储散列以便以后处理
_结果。添加(结果);
}
私有作废通知(IAsyncResult结果)
{
//由于搜索正在长时间运行,我们不想使用EndSendRequest
PartialResultsCollection prc=\u connection.GetPartialResults(结果);
foreach(中国境内的SearchResultEntry条目)
{
OnObjectChanged(新的ObjectChangedEventArgs(条目));
}
}
对象已更改的私有void(ObjectChangedEventArgs args)
{
if(ObjectChanged!=null)
{
ObjectChanged(本,args);
}
}
公共事件事件处理程序对象已更改;
#区域IDisposable成员
公共空间处置()
{
foreach(var结果在_结果中)
{
//结束每个异步搜索
_连接中止(结果);
}
}
#端区
}
公共类ObjectChangedEventArgs:EventArgs
{
public ObjectChangedEventArgs(SearchResultEntry条目)
{
结果=输入;
}
公共SearchResultEntry结果{get;set;}
}
}

<>代码> 我会让你考虑一条完全不同的路径,即使我对你的应用程序一无所知。

更改通知都很好,但也有一些缺点。广告无法扩展到大量的广告。如果您离线一段时间,您会错过一些更改。等等

还有另一种机制,我鼓励你考虑叫DirSync。可以将DirSync看作是通过LDAP提供给您的AD内部复制协议的“原始公开”。DirSync的想法是,你可以发出一个查询,然后说“发生了什么变化?”广告就会回答。答案是一块不透明的饼干。下次再次发出查询时,再次提供cookie,它将告诉您自上次发出cookie以来发生了哪些更改

这其中有很多不错的元素:

  • DirSync有一个很好的规模故事。您可以要求更改1个对象或100万个对象,我们知道DirSync将根据您的需要进行扩展
  • DirSync对于离线一段时间有一个干净的故事。哟