我正在尝试从活动目录中获取更改通知,以便在AD中出现任何问题时可以更新数据库中的数据。我搜索并找到了Ryan Dunn的good example。
我尝试实现他的代码。该应用程序启动时没有任何错误,但没有生成任何通知。有人可以帮我吗?
我的域是win 2008服务器计算机上的corp.am2k8vm.com
,出于测试目的,我在活动目录上的用户很少。
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;}
}
}
最佳答案
尽管我对您的应用一无所知,但我还是会敦促您一起考虑另一条路。
变更通知都很好,但是也有一些缺点。广告无法扩展到其中的大量应用。如果您离线一段时间,则会错过一些更改。等等。
我鼓励您考虑使用另一种机制命名DirSync。将DirSync视为通过LDAP提供给您的AD内部复制协议的“原始显示”。 DirSync的想法是,您可以发出查询并说“更改了什么?”。 AD会回答。答案是一个不透明的cookie。下次再次发出查询时,您将再次提供cookie,它将告诉您自上次发布cookie以来发生了什么变化。
很多好的元素:
假设您获得了dup更改,则需要进行防御性编码,但这对于大多数应用程序来说都是一个合理的假设。
希望这可以帮助。
关于.net - 在.NET中实现Active Directory更改通知,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8527603/