Frage

Dieser Link http://msdn.microsoft.com/en-us/library/aa772153(vs.85).aspx sagt:

Sie können bis zu fünf Benachrichtigungsanforderungen für eine einzige LDAP -Verbindung registrieren. Sie müssen einen speziellen Thread haben, der auf die Benachrichtigungen wartet und schnell verarbeitet. Wenn Sie die Funktion ldap_search_ext aufrufen, um eine Benachrichtigungsanforderung zu registrieren, gibt die Funktion eine Nachrichtenkennung zurück, die diese Anforderung identifiziert. Sie verwenden dann die Funktion LDAP_RESULT, um auf Änderungsbenachrichtigungen zu warten. Wenn eine Änderung eintritt, sendet der Server Ihnen eine LDAP -Nachricht, die die Nachrichtenkennung für die Benachrichtigungsanforderung enthält, die die Benachrichtigung generiert hat. Dies führt dazu, dass die Funktion LDAP_RESULT mit Suchergebnissen zurückkehrt, die das geänderte Objekt identifizieren.

Ich kann kein ähnliches Verhalten finden, das die .NET -Dokumentation durchschaut. Wenn jemand weiß, wie man das in C# macht, wäre ich sehr dankbar zu wissen. Ich möchte sehen, wann die Attribute alle Benutzer im System ändern, damit ich je nachdem, was sich geändert hat, benutzerdefinierte Aktionen ausführen kann.

Ich habe ohne Glück durch Stackoverflow und andere Quellen geschaut.

Vielen Dank.

War es hilfreich?

Lösung

Ich bin mir nicht sicher, ob es das tut, was Sie brauchen, aber schauen Sie sich an http://dunnry.com/blog/ImplementingchangeNotificationssinnet.aspx

Bearbeiten: Text und Code hinzugefügt aus dem Artikel:



Es gibt drei Möglichkeiten, Dinge herauszufinden, die sich in Active Directory (oder Adam) verändert haben. Diese wurden seit einiger Zeit bei MSDN in dem treffend Titel "" Dokumentiert "dokumentiert.Überblick über Veränderungstechniken ". Zusammenfassend:

  1. Umfragen für Änderungen mit usnchangeded. Diese Technik überprüft den Wert von "höchstunterricht", um zu beginnen, und führt dann die Suche nach usnchangierten Werten durch, die anschließend höher sind. Das usnchanged -Attribut wird nicht zwischen Domänencontrollern repliziert. Daher müssen Sie jedes Mal auf denselben Domänencontroller zurückkehren, um Konsistenz zu erhalten. Im Wesentlichen führen Sie eine Suche nach dem höchsten "usnchanged" -Wert + 1 durch und lesen dann in den Ergebnissen, die sie auf gewünschte Weise verfolgen.
    • Vorteile
      • Dies ist der kompatibelste Weg. Alle Sprachen und alle Versionen von .NET unterstützen auf diese Weise, da es sich um eine einfache Suche handelt.
    • Nachteile
      • Der Entwickler gibt es hier viel, um die man sich kümmern kann. Sie erhalten das gesamte Objekt zurück und müssen bestimmen, was sich im Objekt geändert hat (und wenn Sie sich für diese Änderung interessieren).
      • Der Umgang mit gelöschten Objekten ist ein Schmerz.
      • Dies ist eine Umfragetechnik, daher ist es nur in Echtzeit wie oft Sie abfragen. Dies kann je nach Anwendung eine gute Sache sein. Beachten Sie, dass auch Zwischenwerte hier nicht verfolgt werden.
  2. Umfragen für Änderungen unter Verwendung der Dirsync -Kontrolle. Diese Technik verwendet die Option ADS_SEARKPREF_DIRSYNC in ADSI und die Steuerung von LDAP_SERVER_DIRSYNC_OID unter den Covers. Machen Sie einfach eine erste Suche, speichern Sie den Cookie und suchen Sie später erneut und senden Sie den Cookie. Es wird nur die Objekte zurückgegeben, die sich geändert haben.
    • Vorteile
      • Dies ist ein einfaches Modell. Sowohl System.DirectoryServices als auch System.DirectoryServices.Protocols unterstützen diese Option.
      • Die Filterung kann reduzieren, worauf Sie sich kümmern müssen. Wenn meine erste Suche nach allen Benutzern ist "(ObjectClass = user)" "kann ich anschließend bei den Umfragen mit" (sn = dunn) "filtern und nur die Kombination beider Filter zurückerhalten, anstatt sich mit damit auseinanderzusetzen Alles aus dem Intialfilter.
      • Die Option Windows 2003+ entfernt die administrative Einschränkung für die Verwendung dieser Option (Objektsicherheit).
      • Die Option von Windows 2003+ bietet Ihnen auch die Möglichkeit, nur die inkrementellen Werte zurückzugeben, die sich in großen, mehrwertigen Attributen geändert haben. Dies ist eine wirklich schöne Funktion.
      • Befasst sich gut mit gelöschten Objekten.
    • Nachteile
      • Dies ist .NET 2.0+ oder später nur Option. Benutzer von .NET 1.1 müssen die USNchanged Tracking verwenden. Skriptsprachen können diese Methode nicht verwenden.
      • Sie können die Suche nur zu einer Partition gründen. Wenn Sie nur ein bestimmtes OU oder ein bestimmtes Objekt verfolgen möchten, müssen Sie diese Ergebnisse später selbst sortieren.
      • Wenn Sie dies mit Nicht-Windows 2003-Modus-Domänen verwenden, wird die Einschränkung geliefert, dass Sie Replikationen erhalten müssen, um Änderungsberechtigungen (Standard Administrator nur Administrator) zu verwenden.
      • Dies ist eine Wahlverhörtechnik. Es verfolgt auch keine Zwischenwerte. Wenn also ein Objekt, das Sie ändert, ändert sich mehrmals zwischen den Suchvorgängen, erhalten Sie nur die letzte Änderung. Dies kann je nach Anwendung von Vorteil sein.
  3. Änderungen von Benachrichtigungen in Active Directory ändern. Diese Technik registriert eine Suche in einem separaten Thread, der Benachrichtigungen erhält, wenn sich Objekt ändert, der dem Filter entspricht. Sie können bis zu 5 Benachrichtigungen pro asynchronisierter Verbindung registrieren.
    • Vorteile
      • Sofortige Benachrichtigung. Die anderen Techniken erfordern Umfragen.
      • Da dies eine Benachrichtigung ist, erhalten Sie alle Änderungen, selbst die Zwischenstoffe, die in den beiden anderen Techniken verloren gegangen wären.
    • Nachteile
      • Relativ ressourcenintensiv. Sie möchten keine ganze Tonne davon ausführen, da dies zu Skalierbarkeitsproblemen mit Ihrem Controller führen kann.
      • Dies sagt Ihnen nur, ob sich das Objekt geändert hat, aber es sagt Ihnen nicht, wie die Änderung war. Sie müssen herausfinden, ob sich das Attribut, das Sie interessieren, geändert hat oder nicht. Davon abgesehen ist es ziemlich leicht zu erkennen, ob das Objekt gelöscht wurde (zumindest leichter als USNChanged -Umfragen).
      • Sie können dies nur in nicht verwaltetem Code oder mit System.DirectoryServices.Protocols tun.

Zum größten Teil habe ich festgestellt, dass Dirsync in praktisch jeder Situation in praktisch jeder Situation in die Rechnung gepasst hat. Ich habe mich nie die Mühe gemacht, eine der anderen Techniken auszuprobieren. Ein Leser fragte jedoch, ob es eine Möglichkeit gibt, die Änderungsbenachrichtigungen in .NET durchzuführen. Ich dachte, es wäre mit SDS.P möglich, hatte es aber nie versucht. Es stellt sich heraus, dass es möglich ist und eigentlich nicht zu schwer zu tun ist.

Mein erster Gedanke zum Schreiben war, das zu verwenden Beispielcode gefunden auf MSDN (und aus Option Nr. 3) und konvertieren Sie diese einfach in System.DirectoryServices.Protocols. Dies stellte sich als Sackgasse heraus. Die Art und Weise, wie Sie es in SDS.P und die Art und Weise, wie der Beispielcode funktioniert, unterscheidet, ist so unterschiedlich, dass er nicht hilfreich ist. Hier ist die Lösung, mit der ich mich ausgedacht habe:

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;}
}

Es ist eine relativ einfache Klasse, mit der Sie Suchvorgänge registrieren können. Der Trick besteht darin, die GetPartialResults -Methode in der Callback -Methode zu verwenden, um nur die gerade aufgetretene Änderung zu erhalten. Ich habe auch die sehr vereinfachte EventArgs -Klasse aufgenommen, die ich verwende, um die Ergebnisse zurückzugeben. Beachten Sie, ich tue hier nichts gegen Threading und habe keine Fehlerbehandlung (dies ist nur ein Beispiel). Sie können diese Klasse wie so konsumieren:

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();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top