Необъяснимое исключение InvalidOperationException с GroupPrincipal и SAM PrincipalContext - PullRequest
2 голосов
/ 18 января 2010

Я пытаюсь создать принципал следующим образом:

PrincipalContext pc = new PrincipalContext(ContextType.Machine);
GroupPrincipal group = new GroupPrincipal(pc);

group.Name = "Some Group Name";
group.Description = "Some Group Name Description";

group.Save();

Однако, когда код выполняется, я получаю следующее сообщение об исключении:

Система.DirectoryServices.AccountManagement: Недопустимое свойство для этого типа магазина.

Если I не установить свойство Description, приведенный выше код работает отлично,просто нет описания для группы.

Я что-то не так делаю?

Заранее спасибо.

РЕДАКТИРОВАТЬ: Я считаю, что янашли обходной путь для этого (для тех, кто, возможно, заинтересован).Группу можно создать так же, как указано выше:

PrincipalContext pc = new PrincipalContext(ContextType.Machine);
GroupPrincipal group = new GroupPrincipal(pc);
group.Save();

Теперь вы создаете DirectoryEntry и связываете его с вновь созданной группой следующим образом:

string path = "WinNT://" + machineName + "/" + group.SamAccountName;
DirectoryEntry dEntry = new DirectoryEntry(path);

Это позволяетДоступ к свойствам этой группы, но меня интересует описание, поэтому:

dEntry.Properties["description"].Add("Some Decription");
dEntry.CommitChanges();

И это должно быть сделано.

Ответы [ 2 ]

7 голосов
/ 18 января 2010

Ответ переписан

Я получил твой ответ, но он тебе может не понравиться. Информации в интернете мало, но в коде это объяснимо:

  • Когда вы создаете GroupPrincipal , к нему добавляется Context . Этот контекст внутренне имеет скрытый тип: SAMStoreCtx, который наследуется от абстрактного типа StoreCtx;
  • Каждое свойство в GroupPrincipal, которое вы вызываете, будет вызывать IsValidProperty, внутренний член SamStoreCtx;
  • Однако для свойства Name это не так;
  • Внутри SAMStoreCtx есть фрагмент кода, который выглядит следующим образом (вывод Reflector):

    internal override bool IsValidProperty(Principal p, string propertyName)
    {
        ObjectMask none = ObjectMask.None;
        if (!ValidPropertyMap.TryGetValue(propertyName, out none))
        {
            return false;
        }
        if ((MaskMap[p.GetType()] & none) <= ObjectMask.None)
        {
            return false;
        }
        return true;
    }
    
  • Посмотрите внимательно на этот код (это заняло у меня мгновение), и вы заметите ошибку. Строка, сравнивающая битовый флаг с none с использованием оператора and, всегда приводит к ObjectMask.None. Второе выражение if для этого всегда верно .
  • Вызывающий код (свойство Settor of Description) генерирует исключение, когда этот метод возвращает false.

Я считаю, что это ошибка в библиотеке Microsoft. Это происходит только с SAMStoreCtx. Возможно, это нарочно, но поскольку код присутствует, но всегда возвращает false, я полагаю, что программисты намеревались вместо этого использовать оператор or. Проверка моих результатов с другими свойствами, такими как DisplayName, выдает то же исключение, что и ожидалось.

Вы можете связаться с Microsoft по этому поводу и показать им эту ветку. Я не проверял новые бета-версии .NET 4.0, которые могут отображаться по-другому. Вы можете проверить это самостоятельно, загрузив Reflector и загрузив соответствующую сборку .NET.

РЕДАКТИРОВАТЬ: я связался с вами для Microsoft и сообщил об ошибке через connect.microsoft.com здесь . Вы можете следить за вопросом там, если хотите.

2 голосов
/ 09 марта 2012

Вы можете использовать GetUnderlyingObject, чтобы получить DirectoryEntry для группы вместо ее поиска.

var newGroup = new GroupPrincipal(context, groupName);

// You must save first           
newGroup.Save();

var entry = (DirectoryEntry) newGroup.GetUnderlyingObject();

entry.Properties["description"].Add(description);
entry.CommitChanges(); 
...