Sam*_*Sam 11 c# monitor active-directory notify
此链接http://msdn.microsoft.com/en-us/library/aa772153(VS.85).aspx说:
您最多可以在一个LDAP连接上注册五个通知请求.您必须有一个专用线程,等待通知并快速处理它们.当您调用ldap_search_ext函数来注册通知请求时,该函数会返回标识该请求的消息标识符.然后使用ldap_result函数等待更改通知.发生更改时,服务器会向您发送一条LDAP消息,其中包含生成通知的通知请求的消息标识符.这会导致ldap_result函数返回标识已更改对象的搜索结果.
通过.NET文档我找不到类似的行为.如果有人知道如何在C#中做到这一点,我将非常感谢知道.我希望看到系统中所有用户的属性发生变化,以便我可以根据更改的内容执行自定义操作.
我查看了stackoverflow和其他来源没有运气.
谢谢.
stu*_*rtd 18
我不确定它能满足您的需求,但请查看http://dunnry.com/blog/ImplementingChangeNotificationsInNET.aspx
编辑:添加文章中的文字和代码:
有三种方法可以找出Active Directory(或ADAM)中已更改的内容.这些已在MSDN中记录了一段时间,名为" 变更跟踪技术概述".综上所述:
在大多数情况下,我发现DirSync在几乎所有情况下都适合我.我从不打扰尝试任何其他技术.但是,读者询问是否有办法在.NET中进行更改通知.我认为可以使用SDS.P,但从未尝试过.事实证明,这可能并且实际上并不太难.
我写这篇文章的第一个想法是使用在MSDN上找到的示例代码(并从选项#3引用)并简单地将其转换为System.DirectoryServices.Protocols.结果证明这是一个死胡同.你在SDS.P中的方式和示例代码的工作方式是不同的,它没有任何帮助.这是我提出的解决方案:
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;}
}
Run Code Online (Sandbox Code Playgroud)
这是一个相对简单的类,可用于注册搜索.诀窍是在回调方法中使用GetPartialResults方法来仅获取刚刚发生的更改.我还包括了我用来传回结果的非常简化的EventArgs类.注意,我没有做任何关于线程的事情,我没有任何错误处理(这只是一个示例).您可以像这样使用此类:
static void Main(string[] args)
{
using (LdapConnection connect = CreateConnection("localhost"))
{
using (ChangeNotifier notifier = new ChangeNotifier(connect))
{
//register some objects for notifications (limit 5)
notifier.Register("dc=dunnry,dc=net", SearchScope.OneLevel);
notifier.Register("cn=testuser1,ou=users,dc=dunnry,dc=net", SearchScope.Base);
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();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11366 次 |
| 最近记录: |