Проблема DirectorySearcher (или sizelimit возвращаемые объекты или нулевые значения на объектах?) - PullRequest
0 голосов
/ 28 марта 2020

Я уже довольно долго придираюсь к этому и продолжаю биться головой о стену. Я прочитал тонны постов, пытаясь понять это, но, очевидно, я делаю что-то не так. Когда я использую DirectorySearcher с Sizelimit под 1000, он работает нормально ... (ну, код работает нормально, только возвращение первой 1000 представляет много проблем: P) Я пытаюсь получить 4012 групп , Итак, я прочитал, что вместо этого мне нужно использовать PageSize = 1000, который будет возвращать все объекты на нескольких страницах. Отлично, это то, что мне было нужно.

Моя проблема в том, что, когда я пытаюсь это сделать, я получаю нулевые значения, когда пытаюсь посмотреть свойства каждого возвращаемого объекта. Я не понимаю, почему я не нашел других постов с такой же проблемой ... Я представляю, что делаю что-то глупое, поскольку я новичок в C#, поэтому я прошу кого-то, чтобы указать мне : D

То, что я пытаюсь выполнить sh:

Я пытаюсь получить все группы рассылки, в которых в данный момент зарегистрирован пользователь, либо являющийся менеджером или один из менеджеров (в Exchange как владелец, значение AD равно «msExchCoManagedByLink») и отображать эти группы в ListBox.

Функция, которую я пытаюсь использовать для этого:

    private void FillGroups()
        {
            DL_listBox.Items.Clear();
            DirectoryEntry entry = new DirectoryEntry("LDAP://<mydomain>");
            string DN = GetDistinguishedName();

            using (DirectorySearcher searcher = new DirectorySearcher(entry))
            {
                searcher.PageSize = 1000;
                searcher.Filter = string.Format("(&(objectCategory=group)(!(groupType:1.2.840.113556.1.4.803:=-2147483648)))");
                searcher.PropertiesToLoad.Add("displayname");
                searcher.PropertiesToLoad.Add("managedby");
                searcher.PropertiesToLoad.Add("msExchCoManagedByLink");

                SearchResultCollection result = searcher.FindAll();
                foreach (SearchResult grp in result)
                {
                    List<string> DNs = new List<string>();
                    string mgr = grp.Properties["managedby"][0].ToString();
                    string g = grp.Properties["displayname"][0].ToString();
                    foreach (string t in grp.Properties["msExchCoManagedByLink"])
                    {
                        DNs.Add(t);
                    }
                    if (mgr == DN)
                    {
                        DL_listBox.Items.Add(g);
                    }
                    foreach (mgrc in DNs)
                    {
                        if (mgrc == DN)
                        {
                            DL_listBox.Items.Add(g);
                        }
                    }
                }
            }
        }

Ошибка, которую я получаю при запуске этого:

В любой из строк, используя grp.Properties[" "][0]:

System.ArgumentOutOfRangeException: Индекс был вне диапазона. Должен быть неотрицательным и меньше размера коллекции. Имя параметра: index '

При просмотре информации об ошибке возвращаемое значение свойства равно нулю. Я не понимаю, почему это так, если он работает, когда он ограничен 1000.

Я немного прочитал PrincipalSearcher, но не смог проверить, могу ли я опросить значение со-менеджера, используя его. Я также не уверен, что не столкнулся бы с той же проблемой. Буду признателен за любой совет, я буду продолжать пробовать другие вещи, но чувствую, что у меня есть возможность попросить кого-то более опытного, чтобы не тратить больше времени на это :))

Спасибо за чтение, это мое первое сообщение: D


Обновление:

Мне удалось обойти эту проблему после нескольких часов игры с ней, выполнив ниже:

  private void FillGroups()
        {
            DL_listBox.Items.Clear();
            DirectoryEntry entry = new DirectoryEntry("LDAP://<mydomain>");
            using (DirectorySearcher searcher = new DirectorySearcher(entry))
            {
                //searcher.PageSize = 1000;
                searcher.SizeLimit = 200;
                searcher.Filter = string.Format("(&(objectCategory=group)(!(groupType:1.2.840.113556.1.4.803:=-2147483648))(managedby={0}))", GetDistinguishedName());
                searcher.PropertiesToLoad.Add("displayname");

                SearchResultCollection result = searcher.FindAll();
                foreach (SearchResult grp in result)
                {
                    string g = grp.Properties["DisplayName"][0].ToString();
                    DL_listBox.Items.Add(g);
                }

            }

            using (DirectorySearcher dsearcher = new DirectorySearcher(entry))
            {
                //searcher.PageSize = 1000;
                dsearcher.SizeLimit = 200;
                dsearcher.Filter = string.Format("(&(objectCategory=group)(!(groupType:1.2.840.113556.1.4.803:=-2147483648))(msExchCoManagedByLink:={0}))", GetDistinguishedName());
                dsearcher.PropertiesToLoad.Add("displayname");
                dsearcher.PropertiesToLoad.Add("managedby");
                dsearcher.PropertiesToLoad.Add("msExchCoManagedByLink");

                SearchResultCollection result = dsearcher.FindAll();
                foreach (SearchResult grp in result)
                {
                    string g = grp.Properties["DisplayName"][0].ToString();
                    DL_listBox.Items.Add(g);
                }

            }
        }

Я все еще хотел бы понять, почему исходный код не работает, хотя, если кто-нибудь может помочь мне понять, что я был бы благодарен! :)

Ответы [ 2 ]

0 голосов
/ 29 марта 2020

Исключение контактных объектов, вероятно, в любом случае - хорошая вещь, но вы все равно можете столкнуться с этой или схожей проблемой. Проблема в том, что эти атрибуты являются необязательными - у них нет для заполнения чем-либо.

Исключение, которое вы видели («Индекс был вне диапазона»), я бы ожидал только см. атрибут с несколькими значениями, которым не являются displayName и managedBy. Может быть, вы использовали grp.Properties["msExchCoManagedByLink"][0] в какой-то момент?

В случае атрибута с несколькими значениями вы увидите пустую коллекцию, когда она не установлена. Поэтому, когда вы пытаетесь получить доступ к значению по индексу 0, оно выдает это исключение. Вы можете избежать этого, проверив grp.Properties["msExchCoManagedByLink"].Count перед тем, как пытаться получить доступ к значению.

Однако даже в обновленном коде вы можете столкнуться с исключением нулевой ссылки. Атрибут displayName также не является обязательным. Если он не установлен, атрибут вообще не будет существовать в коллекции Properties. (т.е. grp.Properties["displayName"] будет null) Это означает, что grp.Properties["DisplayName"][0].ToString(); сгенерирует исключение нулевой ссылки, если displayName не установлено. Вы можете избежать этого, либо проверив grp.Properties.Contains("displayName") перед установкой:

string g = grp.Properties.Contains("displayName") ? grp.Properties["DisplayName"][0].ToString() : null;

, либо используйте условный оператор null :

string g = grp.Properties["DisplayName"]?[0].ToString();
0 голосов
/ 29 марта 2020

Мне удалось найти ответ где-то еще, но я решил опубликовать его здесь на случай, если кто-нибудь еще столкнется с этой странностью;) Когда я посмотрел на отладчик того, что возвращалось в user.Properties, когда возникло исключение Я видел, что он вытягивал контактный объект, который имел "\" в отображаемом имени. Добавление (objectClass = user) к запросу LDAP удалило их, и все стало работать отлично.

...