- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания C# для профессионалов. Том II - Симон Робинсон
Шрифт:
Интервал:
Закладка:
Запись изменений в объекты также происходит только в кэше. Задание множества свойств не генерирует сетевого трафика. Метод DirectoryEntry.CommitChanges() требуется для очистки кэша и переноса всех измененных данных на сервер. Чтобы снова получить вновь записанные данные из хранилища каталога, можно для чтения свойств использовать метод DirectoryEntry.RefreshCache(). Задание свойства UsePropertyCache как false может быть очень полезно для отладки, чтобы увидеть, какое свойство было изменено неправильно.
Обновление записей каталога
Объекты в активном каталоге обновляются так же легко, как и читаются. Изменение значений возможно после считывания объекта. Чтобы удалить все значения одного свойства, может вызываться метод PropertyValueCollection.Clear(). С помощью метода Add() к свойству могут добавляться новые значения. Remove() и RemoveAt() удаляют специфические значения из коллекции свойства:
using (DirectoryEntry de = new DirectoryEntry!)) {
de.Path =
"LDAP://celticrain/CN=Christian Nagel, " +
"OU=Wrox Press, DC=eichkogelstrasse, DC=local";
if (de.Properties.Contains("mobile")) {
de.Properties["mobile"][0] = "+43 (664) 3434343434";
}
de.CommitChanges();
}
Чтобы изменить значение, зададим ему определенное значение. Посредством следующей строки кода для номера мобильного телефона задается новое значение, если оно существует, с использованием индекса PropertyValueCollection. С помощью индекса значение может только изменяться. Поэтому необходимо всегда проверять методом DirectoryEntry.Properties.Contains(), доступен ли атрибут:
de.Properties["mobile"][0] = "+43 (664) 3434343434";
He забудьте вызвать метод DirectoryEntry.CommitChanges() после создания или обновления новых объектов каталога. Иначе обновляется только кэш, а изменения не посылаются службе каталога.
Создание новых объектов
Новые объекты активного каталога, такие как пользователи, компьютеры, принтеры, контакты и другие программным путем можно создать с помощью класса DirectoryEntries.
Чтобы добавить новые объекты в каталог, мы должны сначала соединиться с объектом-контейнером, подобным организационной единице, куда можно вставить новые объекты. Объекты, которые не могут содержать другие объекты, использовать нельзя. Здесь используется контейнерный объект с известным именем CN=Users, DC=eichkogelstrasse, DC=local:
DirectoryEntry de = new DirectoryEntry();
de.Path = "LDAP://celticrain/CN=Users, " +
"DC=eichkogelstrasse, DC=local";
Можно получить доступ к объекту DirectoryEntries с помощью свойства Children объекта DirectoryEntry:
DirectoryEntries users = de.Children;
Объект DirectoryEntries имеет методы для добавления, удаления, и поиска объектов в коллекции. Здесь создается новый объект пользователя. Для метода Add() нам нужно имя объекта и имя типа. Можно легко получить имена типов с помощью ADSI Edit.
DirectoryEntry user = users.Add("John Doe", "user");
Объект теперь имеет значения свойств по умолчанию. Чтобы присвоить специальные значения свойств, можно добавить свойства с помощью метода Add() свойства Properties. Конечно, все свойства должны существовать в схеме для объекта пользователя. Если определенное свойство не существует, то возникнет исключение COMException "The specified directory service attribute or value doesn't exist" ("Указанный атрибут или значение службы каталога не существует"). Если имена атрибутов правильны, но сервер отказывает во входе в связи с незаконным паролем или пропущенным свойством, исключение COMException будет содержать сообщение "The server is unwilling to process the request" ("Сервер не желает обрабатывать запрос").
user.Properties["company"].Add("Some Company");
user.Properties["department"].Add("Sales");
user.properties["employeeID"].Add("4711");
user.Properties["samAccountName"].Add("John Doe");
user.Properties["userPassword"].Add("someSecret");
В данный момент не все данные записаны в активный каталог. Необходимо очистить кэш:
user.CommitChanges();
Поиск в активном каталоге
Большую часть времени активный каталог будет использоваться для поиска некоторых значений. Это хранилище данных, которое оптимизировано в основном для чтения, поэтому данные будут в основном считываться.
Для поиска в активном каталоге платформа .NET имеет класс DirectorySearcher.
Мы можем использовать поиск только с провайдером LDAP. DirectorySearcher не работает с провайдерами NDS или IIS.
В конструкторе класса DirectorySearcher существуют четыре важные части поиска. Можно также использовать конструктор по умолчанию и определять параметры поиска с помощью свойств.
SearchRootКорень поиска (SearchRoot) определяет, где должен начаться поиск. По умолчанию SearchRoot является корнем домена, который используется в данный момент. SearchRoot определен с помощью свойства Path объекта DirectoryEntry.
FilterФильтр (Filter) определяет значения, которые мы хотим найти. Фильтр является строкой, которая должна быть заключена в круглые скобки.
Операторы отношений, такие как <=, =, >=, в выражениях допускаются. (objectClass = contact) будет искать все объекты типа contact; (lastName>=Nagel) ищет все объекты, где свойство lastName равно или больше Nagel, что означает, что оно следует за ним в алфавитном порядке.
Выражения могут комбинироваться с префиксными операциями & и |. (&(objectClass=user)(description=Auth*)) ищет все объекты типа user, где свойство description начинается со строки Auth. Так как операторы & и | находятся в начале выражения, то с помощью одного префиксного оператора можно комбинировать более двух выражений.
По умолчанию используется фильтр (objectClass=*), поэтому все объекты допустимы. Синтаксис фильтра определен в RFC 2254, "Строковое представление фильтров поиска LDAP". Этот RFC можно найти по адресу www.ietf.org/rfc/rfc2254.txt.
PropertiesToLoadС помощью PropertiesToLoad мы определяем коллекцию StringCollection всех интересующих нас свойств. Как вы уже видели, объекты могут иметь множество свойств. Большинство из них будут не важны для нашего запроса поиска. Мы определяем свойства, загружаемые в кэш. Свойствами по умолчанию, которые мы получаем, если ничего не определено, являются Path и Name для объекта.
SearchScopeSearchScope является перечислением, которое определяет, как глубоко должен распространяться поиск:
□ SearchScope.Base ищет атрибуты только в том объекте, где начинается поиск, поэтому мы получаем максимум один объект.
□ Для SearchScope.OneLevel поиск продолжается в коллекции-потомке базового объекта. Сам базовый объект для поиска не используется.
□ SearchScope.Subtree определяет, что поиск должен спускаться вниз по всему дереву.
По умолчанию для SearchScope используется Subtree.
Пределы поиска
Такой поиск может охватывать несколько доменов. Чтобы ограничить поиск некоторым числом объектов или требуемым временем, необходимо определить несколько дополнительных свойств.
Свойства DirectorySearcher Описание ClientTimeout Максимальное время, в течение которого клиент ожидает, что сервер вернет результат. Если сервер не отвечает, то никаких записей не возвращается. PageSize При постраничном поиске сервер возвращает число объектов, определенных с помощью PageSize, а не весь результат. Это сокращает и время клиента для получения первого ответа, и необходимую память. Сервер посылает клиенту cookie, которое отправляется назад на сервер с запросом следующего поиска, чтобы поиск можно было продолжить в точке, где он закончился. ServerPageTimeLimit Это значение определяет время для постраничного поиска, чтобы вернуть число объектов, которое определено значением PageSize. Если время истекает до достижения значения PageSize, найденные до этого момента объекты возвращаются клиенту. Значение по умолчанию равно -1, что означает бесконечность. ServerTimeLimit Определяет максимальное время, в течение которого сервер будет искать объекты. Когда это время истекает, все найденные до этого момента объекты возвращаются клиенту. По умолчанию используется 120 секунд, и нельзя задать время поиска больше этого значения. ReferalChasing Поиск может распространяться на несколько доменов. Если корень, который определен в SearchRoot, является родительским доменом или корень не был определен, поиск может распространиться на домены-потомки. С помощью этого свойства можно определить, что поиск должен продолжаться на других серверах. ReferalChasingOption.None означает, что поиск не продолжается на другие серверы. С помощью значения ReferalChasingOption.Subordinate можно определить, что поиск должен переходить на домены-потомки. Когда поиск начинается в DC=Wrox, DC=COM, сервер возвращает множество результатов и ссылку на DC=France, DC=Wrox, DC=COM. Клиент может продолжить поиск в поддомене. ReferalChasingOption.External означает, что сервер может направить клиента на независимый сервер, которого нет в поддомене. Это вариант поведения по умолчанию. Для ReferalChasingOption.All возвращаются ссылки на внешние домены и подчиненные домены.В рассматриваемом примере поиска мы хотим найти все объекты пользователей в организационной единице Wrox Press, где свойство description содержит значение Author.