How can I get a custom field from Active Directory in C#? -


i've read plenty of similar stackoverflow questions none seem address issue i'm seeing. if query user using userprincipalname search result 34 properties. none of custom properties returned. if query again using custom property employeenumber result 71 properties. custom properties included.

my issue don't have employeenumber @ run time, userprincipalname. need of custom properties of time. makes sense. here's practice code:

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() 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); // <-- doesn't custom properties //search.filter = string.format("(employeenumber={0})", "11663"); <-- works  var result = search.findone(); // findone(); if (result.properties.contains("employeenumber")) {     //this never happens either :( } 

the above never returns employeenumber field, if uncomment second search.filter line , manually search employeenumber find result , contains of fields need.

edit: found msdn article here describes how extend userprincipal object custom attributes. issue it's giving me empty string every time access though have verified property set in ad! appreciated.

edit 2: here's code custom principal extension:

[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     {                 {             if (searchfilter == null)                 searchfilter = new personsearchfilter(this);              return searchfilter;         }     }      [directoryproperty("employeenumber")]     public string employeenumber     {                 {             if (extensionget("employeenumber").length != 1)                 return string.empty;              return (string)extensionget("employeenumber")[0];         }         set         {             extensionset("employeenumber", value);         }     } } 

and custom search filter:

public class personsearchfilter : advancedfilters {     public personsearchfilter(principal p)         : base(p)     {     }      public void samaccountname(string value, matchtype type)     {         this.advancedfilterset("samaccountname", value, typeof(string), type);     } } 

usage:

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 empty string though ad entries have employeenumber.

edit: active directory: active directory

i more confidant in how fix second method answer first. need specify property in directorysearcher.propertiestoload when search property show up.

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 work. } 

the reason worked string.format("(employeenumber={0})", "11663"); because search clause add automatically gets put in propertiestoload collection.


for first method, think need call directoryentry.refreshcache , pass in property make show up.

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() directoryentry;      entry.refreshcache(new[] {"employeenumber"});      if (entry.properties.contains("employeenumber"))     {      } } 

but not 100% sure if work or not.


for custom user principal, not sure wrong. difference see between doing , have in project know works use [directoryobjectclass("person")] have [directoryobjectclass("user")]. perhaps issue

[directoryrdnprefix("cn")] [directoryobjectclass("user")] //maybe fix it??? public class userprincipalextension : userprincipal { 

Comments

Popular posts from this blog

OpenCV OpenCL: Convert Mat to Bitmap in JNI Layer for Android -

android - org.xmlpull.v1.XmlPullParserException: expected: START_TAG {http://schemas.xmlsoap.org/soap/envelope/}Envelope -

python - How to remove the Xframe Options header in django? -