在.NET中实现Active Directory更改通知
我正在尝试从active directory获取更改通知,以便在我的广告中出现任何更改时可以更新数据库中的数据。我搜索并找到了Ryan Dunn的一篇文章 我试着实现他的代码。应用程序启动时没有任何错误,但不会生成任何通知。有人能帮我吗 我的域名是win 2008服务器上的在.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
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对于离线一段时间有一个干净的故事。哟