2015-07-01 14 views
5

Przeczytałem wiele podobnych pytań dotyczących StackOverflow, ale żaden z nich nie rozwiązuje problemu, który widzę. Jeśli zapytam użytkownika korzystającego z userprincipalname, otrzymam wynik wyszukiwania z dokładnie 34 właściwościami. Żadna z właściwości niestandardowych nie jest zwracana. Jeśli ponownie zapytam, używając właściwości niestandardowej, takiej jak employeeNumber, otrzymam wynik z 71 właściwościami. Wszystkie niestandardowe właściwości są uwzględniane.Jak mogę uzyskać niestandardowe pole z Active Directory w C#?

Mój problem jest to, że nie mają employeeNumber w czasie wykonywania, po prostu userPrincipalName. Muszę odzyskać wszystkie niestandardowe właściwości przez cały czas. Mam nadzieję, że ma to sens. Oto mój kod praktyka:

string sid = ""; 
using (PrincipalContext context = new PrincipalContext(ContextType.Domain)) 
{ 
    UserPrincipal user = UserPrincipal.Current; 
    //sid = user.SamAccountName; 
    sid = user.UserPrincipalName; 
    //sid = user.Sid.ToString(); 

    DirectoryEntry entry = user.GetUnderlyingObject() as DirectoryEntry; 
    if (entry.Properties.Contains("employeeNumber")) 
    { 
     //this doesn't work 
    } 
} 

DirectoryEntry ldapConnection = new DirectoryEntry("companyname.com"); 
ldapConnection.Path = "LDAP://DC=companyname,DC=com"; 
ldapConnection.AuthenticationType = AuthenticationTypes.Secure; 

DirectorySearcher search = new DirectorySearcher(ldapConnection); 
search.Filter = string.Format("(&(ObjectClass=user)(userprincipalname={0}))", sid); // <-- this doesn't get custom properties 
//search.Filter = string.Format("(employeeNumber={0})", "11663"); <-- this works 

var result = search.FindOne(); // FindOne(); 
if (result.Properties.Contains("employeeNumber")) 
{ 
    //this never happens either :(
} 

Powyższy nigdy zwraca pole employeeNumber, ale gdybym odkomentowaniu drugą linię search.Filter i ręcznie wyszukiwać według employeeNumber znajdę wynikiem i zawiera wszystkie pola tego potrzebuję.

EDYCJA: Znalazłem bardzo dobry artykuł MSDN Here, który opisuje, jak rozszerzyć obiekt UserPrincipal, aby uzyskać niestandardowe atrybuty. Jedyny problem polega na tym, że za każdym razem, gdy uzyskuję dostęp do tej funkcji, otrzymuję pusty ciąg znaków, mimo że zweryfikowałem, że właściwość jest ustawiona w AD! Każda pomoc jest doceniana.

EDIT 2: Oto kod dla rozszerzenia niestandardowe głównej:

[DirectoryRdnPrefix("CN")] 
[DirectoryObjectClass("Person")] 
public class UserPrincipalExtension : UserPrincipal 
{ 
    public UserPrincipalExtension(PrincipalContext context) 
     : base(context) 
    { 
    } 

    public UserPrincipalExtension(PrincipalContext context, string samAccountName, string password, bool enabled) 
     : base(context, samAccountName, password, enabled) 
    { 
    } 

    public static new UserPrincipalExtension FindByIdentity(PrincipalContext context, IdentityType type, string identityValue) 
    { 
     return (UserPrincipalExtension)FindByIdentityWithType(context, typeof(UserPrincipalExtension), type, identityValue); 
    } 

    PersonSearchFilter searchFilter; 
    new public PersonSearchFilter AdvancedSearchFilter 
    { 
     get 
     { 
      if (searchFilter == null) 
       searchFilter = new PersonSearchFilter(this); 

      return searchFilter; 
     } 
    } 

    [DirectoryProperty("employeeNumber")] 
    public string EmployeeNumber 
    { 
     get 
     { 
      if (ExtensionGet("employeeNumber").Length != 1) 
       return string.Empty; 

      return (string)ExtensionGet("employeeNumber")[0]; 
     } 
     set 
     { 
      ExtensionSet("employeeNumber", value); 
     } 
    } 
} 

i filtr Custom Search:

public class PersonSearchFilter : AdvancedFilters 
{ 
    public PersonSearchFilter(Principal p) 
     : base(p) 
    { 
    } 

    public void SAMAccountName(string value, MatchType type) 
    { 
     this.AdvancedFilterSet("sAMAccountName", value, typeof(string), type); 
    } 
} 

Zastosowanie:

UserPrincipalExtension filter = new UserPrincipalExtension(context); 
filter.AdvancedSearchFilter.SAMAccountName(UserPrincipal.Current.SamAccountName, MatchType.Equals); 
PrincipalSearcher search = new PrincipalSearcher(filter); 

foreach (var result in search.FindAll()) 
{ 
    var q = (UserPrincipalExtension)result; 
    var m = q.EmployeeNumber; 
} 

var m jest zawsze pusty ciąg znaków, mimo że wpisy ALL AD mają numer EmployerNumber.

EDIT: Z aktywnym katalogu: Active Directory

Odpowiedz

1

jestem bardziej zaufany w jaki sposób naprawić swój drugi sposób więc odpowiem, że w pierwszej kolejności. Musisz określić właściwość w DirectorySearcher.PropertiesToLoad podczas wyszukiwania właściwości, która ma się pojawić.

DirectorySearcher search = new DirectorySearcher(ldapConnection); 
search.Filter = string.Format("(&(ObjectClass=user)(userprincipalname={0}))", sid); 
search.PropertiesToLoad.Add("employeeNumber"); 

var result = search.FindOne(); // FindOne(); 
if (result.Properties.Contains("employeeNumber")) 
{ 
    //This should now work. 
} 

Powodem pracował dla string.Format("(employeeNumber={0})", "11663"); dlatego jakakolwiek klauzula wyszukiwania dodać automatycznie pobiera wprowadzić do kolekcji PropertiesToLoad.


przypadku pierwszego sposobu, myślę, że trzeba zadzwonić DirectoryEntry.RefreshCache i przechodzą na własność, aby pokazać się.

string sid = ""; 
using (PrincipalContext context = new PrincipalContext(ContextType.Domain)) 
{ 
    UserPrincipal user = UserPrincipal.Current; 
    //sid = user.SamAccountName; 
    sid = user.UserPrincipalName; 
    //sid = user.Sid.ToString(); 

    DirectoryEntry entry = user.GetUnderlyingObject() as DirectoryEntry; 

    entry.RefreshCache(new[] {"employeeNumber"}); 

    if (entry.Properties.Contains("employeeNumber")) 
    { 

    } 
} 

Ale nie jestem w 100% pewien, czy to zadziała, czy nie.


Dla użytkownika niestandardowego użytkownika, nie jestem pewien, co jest nie tak. Jedyną różnicą między tym, co robisz, a tym, co robię w projekcie, który działa, a wiem, że działa, jest użycie [DirectoryObjectClass("Person")], ale mam [DirectoryObjectClass("user")].Być może to jest kwestia

[DirectoryRdnPrefix("CN")] 
[DirectoryObjectClass("user")] //Maybe this will fix it??? 
public class UserPrincipalExtension : UserPrincipal 
{ 
+0

Dziękuję bardzo za pomysły, ale niestety nie zadziałały. Odświeżanie pamięci podręcznej było dobrym pomysłem, ale wartość była wciąż pustym ciągiem. Drugi pomysł, w którym ustawiłeś PropertiesToLoad, był świetnym pomysłem, ale nie zadziałał. Wziąłem jeszcze trochę rozumowanie i dodałem employeeNumber do mojego zapytania, aby spróbować wymusić jego załadowanie, na przykład: search.Filter = string.Format ("(& (ObjectClass = user) (| (employeeNumber = 99999) (userprincipalname) = {0}))) ", sid); <- możesz zobaczyć mojego fałszywego pracownika numer w moim stanie LUB. Bez żadnego przypadku. – BrianLegg

+0

Hmm. Czy jesteś w 100% pewien, że pracownik, którego szukasz, ma wartość w tej nieruchomości. Nie wiem, ale może nie wyświetla się, jeśli nie ustawiono żadnej wartości. Spójrz na [moje stare pytanie] (http://stackoverflow.com/questions/14566887/how-to-set-a-binary-attribute-when-using-a-accountmanagement-extension-class), może może dać ci pomysł. –

+0

Właśnie sprawdziłem dwa razy i jest tam. Zapytałem o pracownika 11663 (ja) i wróciłem do obiektu z 71 nieruchomościami. EmployeeNumber był jednym z nich. Zapytałem ponownie, używając mojego imienia, a następnie mojego sida, następnie przez moją nazwę użytkownika, a wszystkie 3 dały mi ten sam przedmiot z powrotem, ale pominąłem właściwość numeru pracownika. Sprawdzę twoje stare pytanie, dzięki. – BrianLegg

Powiązane problemy