Question

Ce lien http://msdn.microsoft.com /en-us/library/aa772153(VS.85).aspx dit:

Vous pouvez enregistrer jusqu'à cinq demandes de notification sur une seule connexion LDAP. Vous devez avoir un thread dédié qui attend les notifications et les traite rapidement. Lorsque vous appelez la fonction ldap_search_ext pour enregistrer une demande de notification, la fonction retourne un identificateur de message qui identifie cette demande. Vous utilisez alors la fonction de ldap_result attendre les notifications de modification. Lorsqu'un changement se produit, le serveur vous envoie un message LDAP contenant l'identifiant de message pour la demande de notification qui a généré la notification. Cela provoque la fonction ldap_result pour retourner des résultats de recherche qui permettent d'identifier l'objet qui a changé.

Je ne peux pas trouver un comportement similaire en regardant à travers la documentation .NET. Si quelqu'un sait comment faire cela en C # Je serais très reconnaissant de savoir. Je cherche à voir lorsque les attributs changent sur tous les utilisateurs dans le système afin que je puisse effectuer des actions personnalisées en fonction de ce qui a changé.

Je l'ai regardé à travers stackoverflow et d'autres sources sans chance.

Merci.

Était-ce utile?

La solution

Je ne suis pas sûr qu'il fait ce que vous avez besoin, mais un coup d'oeil à http: // dunnry. com / blog / ImplementingChangeNotificationsInNET.aspx

Edit: Ajout de texte et le code de l'article:



Il y a trois façons de déterminer les choses qui ont changé dans Active Directory (ou ADAM). Celles-ci ont été documentés depuis un certain temps sur le site MSDN dans le bien nommé « Aperçu des changements techniques de suivi" . En résumé:

  1. Polling pour les changements à l'aide uSNChanged. Cette technique vérifie la valeur « highestCommittedUSN » pour démarrer et effectue ensuite des recherches pour les valeurs « uSNChanged » qui sont plus élevés par la suite. L'attribut « uSNChanged » est pas répliqué entre les contrôleurs de domaine, vous devez donc revenir au même contrôleur de domaine à chaque fois pour la cohérence. Essentiellement, vous effectuez une recherche à la recherche de la plus haute valeur « uSNChanged » + 1, puis lire dans les résultats les suivi de quelque façon que vous le souhaitez.
    • Avantages
      • Ceci est la façon la plus compatible. Toutes les langues et toutes les versions de .NET prennent en charge cette façon car il est une simple recherche.
    • Inconvénients
      • Il y a beaucoup ici pour le développeur de prendre en charge. Vous obtenez l'objet entier en arrière, et vous devez déterminer ce qui a changé sur l'objet (et si vous vous souciez de ce changement).
      • Traiter avec des objets supprimés est une douleur.
      • Ceci est une technique de vote, il est donc uniquement en temps réel comme la fréquence de requête. Cela peut être une bonne chose en fonction de l'application. Remarque, les valeurs intermédiaires ne sont pas suivies ici non plus.
  2. Polling pour les changements Utilisation du contrôle DirSync. Cette technique utilise l'option ADS_SEARCHPREF_DIRSYNC dans ADSI et le contrôle de LDAP_SERVER_DIRSYNC_OID sous les couvertures. Il suffit de faire une recherche initiale, stocker le cookie, puis effectuez une recherche plus tard encore et envoyer le cookie. Il retourne uniquement les objets qui ont changé.
    • Avantages
      • Ceci est un modèle facile à suivre. Les deux System.DirectoryServices et System.DirectoryServices.Protocols prennent en charge cette option.
      • Le filtrage peut réduire ce que vous devez embêter avec. À titre d'exemple, si ma recherche initiale est pour tous les utilisateurs « (objectClass = user) », je peux ensuite filtrer sur les sondages avec « (sn = dunn) » et ne reçoivent que la combinaison des deux filtres, au lieu d'avoir à traiter tout du filtre intial.
      • l'option de Windows 2003+ supprime la limitation administrative pour l'utilisation de cette option (de sécurité de l'objet).
      • l'option de Windows 2003+ vous donnera également la possibilité de retourner uniquement les valeurs supplémentaires qui ont changé dans les grands attributs à valeurs multiples. Ceci est une caractéristique très agréable.
      • Offres bien avec des objets supprimés.
    • Inconvénients
      • Ceci est .NET 2.0+ ou tard seule option. Les utilisateurs de .NET 1.1 devront utiliser uSNChanged de suivi. Les langages de script ne peuvent pas utiliser cette méthode.
      • Vous ne pouvez limiter la portée de la recherche à une partition. Si vous voulez seulement suivre une unité d'organisation ou un objet particulier, vous devez trier les résultats vous plus tard.
      • L'utilisation de ce mode avec des domaines non-Windows 2003 est livré avec la restriction que vous devez avoir réplication obtenir les autorisations changements (par défaut uniquement admin) à utiliser.
      • Ceci est une technique d'interrogation. Il ne suit pas les valeurs intermédiaires eitsa. Donc, si un objet que vous voulez suivre les changements entre les recherches plusieurs fois, vous n'obtiendrez le dernier changement. Cela peut être un avantage en fonction de l'application.
  3. Modifier Notifications active Directory. Cette technique enregistre une recherche sur un thread séparé qui recevra des notifications lorsque des modifications d'objets correspondant au filtre. Vous pouvez enregistrer jusqu'à 5 notifications par connexion asynchrone.
    • Avantages
      • Notification instantanée. Les autres techniques requièrent une interrogation.
      • Parce que c'est une notification, vous obtiendrez tous les changements, même les intermédiaires qui auraient été perdus dans les deux autres techniques.
    • Inconvénients
      • ressource relativement intensive. Vous ne voulez pas faire une tonne entière de ces car cela pourrait causer des problèmes d'évolutivité avec votre contrôleur.
      • Cela ne vous indique si l'objet a changé, mais il ne vous dit pas ce que le changement a été. Vous devez savoir si l'attribut que vous aimez a changé ou non. Cela étant dit, il est assez facile de dire si l'objet a été supprimé (plus facile que uSNChanged vote au moins).
      • Vous ne pouvez le faire en code non managé ou avec System.DirectoryServices.Protocols.

Pour la plupart, j'ai trouvé que DirSync a la facture pour s'adapter moi dans pratiquement toutes les situations. Je jamais pris la peine d'essayer l'une des autres techniques. Cependant, un lecteur a demandé s'il y avait un moyen de faire les notifications de changement dans .NET. Je me suis dit qu'il était possible en utilisant SDS.P, mais avais jamais essayé. Il s'avère, il est possible et en fait pas trop difficile à faire.

Ma première pensée à écrire c'était d'utiliser le exemple de code trouvé sur MSDN ( et référencé à partir de l'option n ° 3) et simplement convertir cela System.DirectoryServices.Protocols. Ce avéré être une impasse. La façon dont vous le faites dans SDS.P et la façon dont les œuvres de code exemple sont assez différents qu'il est d'aucune aide. Voici la solution que je suis venu avec:

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

Il est une classe relativement simple que vous pouvez utiliser pour enregistrer les recherches. L'astuce utilise la méthode GetPartialResults dans la méthode de rappel pour obtenir seulement le changement qui vient de se produire. J'ai également inclus la classe EventArgs très simplifiée J'utilise pour passer des résultats de retour. Remarque, je ne fais rien de filetage ici et je n'ai pas de gestion des erreurs (ce qui est juste un échantillon). Vous pouvez consommer cette classe comme ceci:

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();
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top