InsidiousBeing Ответов: 1

Directorysearcher с помощью размер страницы вместо того, чтобы ошибку потребления sizelimit


Всем Привет,

Эта проблема бросает меня в петлю, потому что я не понимаю, что я делаю неправильно. Когда я пытаюсь выполнить этот поиск с помощью PageSize=1000, я получаю странную ошибку index out of bounds для всех моих запросов свойств. Когда я комментирую PageSize и использую Sizelimit, он отлично работает. Я работаю с 12k пользователями, так что, очевидно, Sizelimit не будет работать для меня.

То, что я пытаюсь сделать:
У меня есть текстовое поле, которое я использую в качестве поля поиска, и я пытаюсь отфильтровать результаты поиска в списке под ним, когда пользователь вводит имя.

Моя функция:
<pre>     public void FillUsers()
        {
            DirectoryEntry entry = new DirectoryEntry("LDAP://<mydomain>", null, null, AuthenticationTypes.Secure);
            Dictionary<int, string> UserCollection= new Dictionary<int, string>();
            using (DirectorySearcher usearcher = new DirectorySearcher(entry))
            {
                //usearcher.PageSize = 1000;
                usearcher.SizeLimit = 500;
                usearcher.Filter = string.Format("(&(objectCategory=Person)(mail=*))");
                usearcher.PropertiesToLoad.Add("displayname");
                usearcher.PropertiesToLoad.Add("samaccountname");

                using (SearchResultCollection result = usearcher.FindAll())
                {
                    int count = 0;
                    foreach (SearchResult user in result)
                    {
                        if (user.Properties["DisplayName"].Count >= 0 && !string.IsNullOrEmpty(user.Properties["DisplayName"][0].ToString()) && user.Properties["samaccountname"].Count >= 0 && !string.IsNullOrEmpty(user.Properties["samaccountName"][0].ToString()))
                        {
                            count++;
                            string u = user.Properties["DisplayName"][0].ToString() + " (" + user.Properties["samaccountname"][0].ToString() + ")";
                            UserCollection.Add(count, u);
                        }
                    }
                }

                DataTable dt = new DataTable();

                dt.Columns.Add("Key", typeof(int));

                dt.Columns.Add("Value");

                foreach (KeyValuePair<int, string> pair in UserCollection)
                { 
                    dt.Rows.Add(pair.Key, pair.Value);
                }

                bs.DataSource = dt;

                AddMbrs_listBox.DisplayMember = "Value";
                AddMbrs_listBox.ValueMember = "Key";

                AddMbrs_listBox.DataSource = bs;
            }
            entry.Dispose();
        }



И вызов textchanged:
private void Addmbr_search_TextChanged(object sender, EventArgs e)
        {
            if (Addmbr_search.Text != null)
            {
                bs.Filter = "Value LIKE '" + this.Addmbr_search.Text + "%'";
                FillUsers();
            }
        }


Любая помощь, которую вы могли бы оказать, была бы потрясающей... Я очень новичок в C#, поэтому уверен, что мне есть чему поучиться, но последние 7 часов я провел в никуда, пытаясь решить эту проблему самостоятельно (к моему большому разочарованию), поэтому я решил, что пришло время для некоторых рекомендаций :)

Что я уже пробовал:

Многое из того, что я пробовал, все еще находится в коде, после того как я провел много исследований в интернете... но я сделал следующее:

- добавил он.
if (user.Properties["DisplayName"].Count >= 0 && !string.IsNullOrEmpty(user.Properties["DisplayName"][0].ToString()) && user.Properties["samaccountname"].Count >= 0 && !string.IsNullOrEmpty(user.Properties["samaccountName"][0].ToString()))
заявление, основанное на большом количестве отзывов на форуме, утверждающих, что он возвращает пустую коллекцию, что это не так, но чувствовал, что это было хорошо иметь там в любом случае :)

- экспериментировал с ServerPageTimeLimit и ServerTimeLimit, думая, что, возможно, это был тайм-аут моего соединения при попытке вызвать страницу, но, похоже, не имел никакого эффекта.

- Попробовал обходной путь, когда я использовал текст searchbox в качестве входной переменной + * и добавил его в фильтр поиска LDAP, чтобы было нормально возвращать SizeLimit=200. Это "сработало", но мне очень не нравится идея делать вызов LDAP каждый раз, когда текстовое поле обновляется.

В этот момент я решил, что мне действительно нужно заставить это работать так, как, кажется, все остальные онлайн работают, поэтому я могу ввести его в источник данных и отфильтровать против него.

1 Ответов

Рейтинг:
6

phil.o

Странно получать четкие результаты, просто меняя метод поиска.
Я заметил, что вы не используете точный корпус для имен свойств LDAP. Может ли быть так, что поиск без страницы выполняет поиск без учета регистра, в то время как поиск по странице будет нуждаться в правильном корпусе? Ты можешь попробовать

usearcher.PropertiesToLoad.Add("displayName");
usearcher.PropertiesToLoad.Add("sAMAccountName");
и посмотрите, будет ли это иметь какой-либо эффект.

Что происходит при отладке? Что user.Properties содержать на странице поиска?


InsidiousBeing

Эй, Фил.,

Спасибо, что откликнулись. Это не было похоже на имя-оболочку, однако, глядя на пользователя.Свойства в отладчике указали на эту проблему. Он также вытягивал контактные объекты, и ему не нравился контакт, который имел "\" в имени дисплея. Как только я добавил (objectClass=user) в запрос, бум! сработало как по волшебству!

Большое спасибо, подумал, что мне не хватает чего-то простого! :)

Желаю вам отличных выходных!

phil.o

Добро пожаловать, хорошего вам уик-энда!