0

Below is my code. I want to retrieve all the users whose first name or last name is same in a grid. But here am getting the name itself in the grid sorted.

I'm giving user a choice to enter user name. Once he enter the name I should be able to search in Active Directory and return all user starting with that text entered by the user.

I should be able to display all possibilities, for example if user enters adam I should give him choice to select whether he want to see adam josef or adam john e.t.c.

Any suggestion will be helpful.

Here is the code

       DirectoryEntry de = new DirectoryEntry("ADConnection");

        DirectorySearcher deSearch = new DirectorySearcher(de);

        //set the search filter    
        deSearch.SearchRoot = de;
        String UserName = txt_To.Text;
        deSearch.Filter = "(&(objectCategory=user)(GivenName=*" + UserName + "*))";
        string[] arrPropertiesToLoad = { "sn" };
        deSearch.PropertiesToLoad.AddRange(arrPropertiesToLoad);

      SearchResultCollection sResultColl = deSearch.FindAll();//Getting undefined error



        Gridview1.DataSource = sResultColl ;
        Gridview1.DataBind();

Here is the stack trace

[COMException (0x80004005): Unspecified error]
System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) +439513
System.DirectoryServices.DirectoryEntry.Bind() +36
System.DirectoryServices.DirectoryEntry.get_AdsObject() +31
System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne) +78
System.DirectoryServices.DirectorySearcher.FindAll() +9
Certificate.WebForm4.btngo0_Click(Object sender, EventArgs e) in C:\Users\273714\documents\visual studio 2010\Projects\Certificate\Certificate\WebForm4.aspx.cs:202
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +118
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +112
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563

6
  • If the username i give is sam, in the grid am getting it as S A M in vertical line. If i uncomment the lines am getting undefined exception. Commented Nov 8, 2012 at 8:01
  • what do you mean undefined exception? Could you show this exception and callstack? Commented Nov 8, 2012 at 8:04
  • The stack trace is in the question. I changed the code by uncommenting the lines. Where am i gng wrong? :( Commented Nov 8, 2012 at 8:22
  • Call stack- > Certificate.DLL!Certificate.WebForm4.btngo0_Click(object sender, System.EventArgs e) Line 202 + 0xa bytes C# Commented Nov 8, 2012 at 8:24
  • Look at this: stackoverflow.com/questions/7892655/… Commented Nov 8, 2012 at 8:48

2 Answers 2

2

You can use a PrincipalSearcher and a "query-by-example" principal to do your searching:

// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

// define a "query-by-example" principal - here, we search for a UserPrincipal 
// and with the first name (GivenName) of "Bruce" and a last name (Surname) of "Miller"
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.GivenName = "*" + UserName + "*";

// create your principal searcher passing in the QBE principal    
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);

// find all matches
foreach(var found in srch.FindAll())
{
    // do whatever here - "found" is of type "Principal" - it could be user, group, computer.....          
}

If you haven't already - absolutely read the MSDN article Managing Directory Security Principals in the .NET Framework 3.5 which shows nicely how to make the best use of the new features in System.DirectoryServices.AccountManagement. Or see the MSDN documentation on the System.DirectoryServices.AccountManagement namespace.

Of course, depending on your need, you might want to specify other properties on that "query-by-example" user principal you create:

  • DisplayName (typically: first name + space + last name)
  • SAM Account Name - your Windows/AD account name
  • User Principal Name - your "[email protected]" style name

You can specify any of the properties on the UserPrincipal and use those as "query-by-example" for your PrincipalSearcher.

Update: if you want to find a bunch of users and bind those to a gridview, use this code:

// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

// define a "query-by-example" principal - here, we search for a UserPrincipal 
// and with the first name (GivenName) of "Bruce" and a last name (Surname) of "Miller"
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.GivenName = "*" + UserName + "*";

// create your principal searcher passing in the QBE principal    
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);

var results = srch.FindAll();

Gridview1.DataSource = results; 
Gridview1.DataBind();

Don't iterate twice over all the data returned! (as in your comment ) .....

Update #2: with the S.DS.AM classes, you always get the complete class - there's nothing you can do about this. If you want to select only specific LDAP attributes, you need to use your original approach.

From that approach, you need to make sure to create the root of the DirectorySearcher on a container - e.g. the OU=Users container - NOT on an individual AD object like a specific user.

So try using this code:

// define a *CONTAINER* as the root of your searcher!
DirectoryEntry de = new DirectoryEntry("LDAP://OU=Users,OU=NJY,OU=NewJersey,OU=USA,OU=NorthAmerica,OU=America,OU=gunt,DC=xxx,DC=com");

DirectorySearcher deSearch = new DirectorySearcher(de);

// set the search filter    
string UserName = txt_To.Text;

deSearch.Filter = string.Format("(&(objectCategory=user)(givenName=*{0}*))", UserName);
deSearch.PropertiesToLoad.Add("sn");

SearchResultCollection sResultColl = deSearch.FindAll();

Gridview1.DataSource = sResultColl;
Gridview1.DataBind();

Does that work?

Sign up to request clarification or add additional context in comments.

15 Comments

I think i got what i wanted ..but how can i bind the result to grid.i used Gridview1.DataSource = found; Gridview1.DataBind(); but got error
its taking very long time.is there a way to reduce the time, like just displaying the firstname with last name or anything like that.
foreach (var found in srch.FindAll()) { string result = srch.FindAll().ToString(); Gridview1.DataSource = result; Gridview1.DataBind();// do // do whatever here - "found" is of type "Principal" - it could be user, group, computer..... } This is how i have used
@user1665707: no wonder it's slow! You're iterating over all users found, and then you're doing a .FindAll() again - for each user...... see my update
Oh fine then will speak to the concerned person regarding this. Thank You for the help.
|
0
deSearch.Filter = "(&(objectCategory=user)(givenName=*" + UserName + "*))";

Works fine

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.