В этой ссылке http://msdn.microsoft.com/en-us/library/aa772153 (По сравнению с 85) .aspx говорится:
Можно зарегистрировать до пяти запросов уведомления на единственном соединении LDAP. У Вас должен быть специализированный поток, который ожидает уведомлений и обрабатывает их быстро. Когда Вы вызываете ldap_search_ext функцию для регистрации запроса уведомления, функция возвращает идентификатор сообщения, который определяет тот запрос. Вы тогда используете функцию ldap_result для ожидания уведомлений об изменении. Когда изменение происходит, сервер отправляет Вам сообщение LDAP, которое содержит идентификатор сообщения для запроса уведомления, который генерировал уведомление. Это заставляет функцию ldap_result возвращаться с результатами поиска, которые определяют объект, который изменился.
Я не могу найти подобное поведение, просматривающее документацию.NET. Если кто-либо знает, как сделать это в C#, я был бы очень благодарен знать. Я надеюсь видеть, когда атрибуты изменяются на всех пользователях в системе, таким образом, я могу выполнить пользовательские действия в зависимости от того, что изменилось.
Я просмотрел stackoverflow и другие источники без удачи.
Спасибо.
] Я не уверен, что он делает то, что вам нужно, но посмотрите на [] http://dunnry.com/blog/ImplementingChangeNotificationsInNET.aspx[][
]. [] Правка: Добавлен текст и код из статьи: [
]. [][
][] Есть три способа выяснить вещи, которые изменились в Active Directory (или ADAM). Они были задокументированы в течение некоторого времени в MSDN в уместном названии "[]Overview of Change Tracking Techniques"[]. Вкратце:[
] [] [
] По большей части я обнаружил, что 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;}
}
]
[] Это относительно простой класс, который можно использовать для регистрации поиска. Хитрость заключается в использовании метода 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();
}
]