locked
Help with AD phone book RRS feed

  • Question

  • User1540266618 posted

    Hello

    I'm in the middle of trying to build an "AD phone book", and this being my first try at asp.net, I have a few questions that I hope some of you might be able to help with:

    1. Is it correct, that PageSize equals the max size of the result set?
    2. Is there a way to make asp cache the search result, so the domain controller won't be to bother by all the lookups, and also to speed up searching?
    3. I've been trying to make a "more info" button, that when clicked, should result in a lookup in the AD, for additional information about the person (e.g. I could do the search with GC, and then lookup more info with LDAP), however, I've been unable to figure out how to see, what button was clicked (there is a "more info" button in each row). I small hint would make my day!
    4. I have also had a hard time figuring out how to make my GridView control sort the search result. I would basically like to be able to sort each column alphabetically. Help me out :)

    My code is included below; any input on it is also very welcome.

    Thanks and best regards, Egil.

    Ps.: dunnry, get that book of your out already :)
    Pss.: I couldn't figure out how to post the code formatted, if some admin would add the appropriate tags to my post, please do so.

    HTML File (header removed, no none standard things in that):

    <body>
        <form id="form1" runat="server">
        <div id="divContent">
            <h1>Search for people</h1>
            <asp:TextBox ID="txtSearch" runat="server" ToolTip="Enter search criteria here" Width="250px" Wrap="False" TabIndex="1"></asp:TextBox>
            <asp:Button ID="btnSearch" runat="server" OnClick="btnSearch_Click" Text="Search" />
            <br />
            <br />
            <asp:Label ID="lblSearchStatus" runat="server" Font-Bold="True" Visible="False"></asp:Label>
            <br />
            <br />
            <asp:GridView ID="gvSearchResult" runat="server" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" HorizontalAlign="Center">
                <Columns>
                    <asp:BoundField DataField="LogonName" HeaderText="Short name:" />
                    <asp:BoundField DataField="FullName" HeaderText="Name:" NullDisplayText="n/a" />
                    <asp:BoundField DataField="Phone" HeaderText="Phone:" />
                    <asp:BoundField DataField="Mobile" HeaderText="Mobile:" NullDisplayText="n/a" />
                    <asp:BoundField DataField="Email" HeaderText="Email:" HtmlEncode="False" />
                    <asp:BoundField DataField="Office" HeaderText="Office:" />
                    <asp:BoundField DataField="Department" HeaderText="Department:" />
                    <asp:ButtonField ButtonType="Button" DataTextField="MoreInfo" HeaderText="More info:" Text="More..." />
                </Columns>
            </asp:GridView>
            <br />
            <asp:Label ID="lblMore" runat="server" Text="" Visible="false"></asp:Label>
        </div>
        </form>
    </body>

    Code behind file:

    public partial class SearchForPeople : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e) {
        }

        protected void btnSearch_Click(object sender, EventArgs e) {
            DirectoryEntry searchRoot = new DirectoryEntry("LDAP://dev-srv-01/DC=dev,DC=local",
                                                           "dev.local\\administrator",
                                                           "pass",
                                                           AuthenticationTypes.Secure);

            // We are responsible to dispose this!
            using (searchRoot) {
                // Build the search filter.
                string searchFilter = "(&(objectClass=person)(objectClass=user)";
                // Add search string if specified.
                if (txtSearch.Text != "")
                    searchFilter += "(cn=*" + txtSearch.Text + "*))";
                else searchFilter += ")";

                // Instantiate ds object.
                DirectorySearcher ds = new DirectorySearcher(searchRoot, searchFilter);

                // Enable paging for large queries
                ds.PageSize = 500;

                using(SearchResultCollection searchResults = ds.FindAll()) {

                    if(searchResults.Count > 0) {
                        // make the People table and its columns
                        DataTable tblPeople = new DataTable("People");

                        // Holds the columns and rows as they are being added.
                        DataColumn col;
                        DataRow row;

                        // Create LogonName column
                        col = new DataColumn("LogonName", System.Type.GetType("System.String"));
                        col.DefaultValue = "";
                        tblPeople.Columns.Add(col);

                        // Create FullName column
                        col = new DataColumn("FullName", System.Type.GetType("System.String"));
                        col.DefaultValue = "";
                        tblPeople.Columns.Add(col);

                        // Create Phone column
                        col = new DataColumn("Phone", System.Type.GetType("System.String"));
                        col.DefaultValue = "";
                        tblPeople.Columns.Add(col);

                        // Create Mobile column
                        col = new DataColumn("Mobile", System.Type.GetType("System.String"));
                        col.DefaultValue = "";
                        tblPeople.Columns.Add(col);

                        // Create Email column
                        col = new DataColumn("Email", System.Type.GetType("System.String"));
                        col.DefaultValue = "";
                        tblPeople.Columns.Add(col);

                        // Create Office column
                        col = new DataColumn("Office", System.Type.GetType("System.String"));
                        col.DefaultValue = "";
                        tblPeople.Columns.Add(col);

                        // Create Department column
                        col = new DataColumn("Department", System.Type.GetType("System.String"));
                        col.DefaultValue = "";
                        tblPeople.Columns.Add(col);

                        // Create More info column
                        col = new DataColumn("MoreInfo");
                        tblPeople.Columns.Add(col);

                        // Iterate over all the results in the resultset.
                        foreach(SearchResult result in searchResults) {
                            row = tblPeople.NewRow();
                            // Getting values
                            // Display Name
                            if(result.Properties.Contains("samaccountname"))
                                row["LogonName"] = result.Properties["samaccountname"][0].ToString();

                            // Display Name
                            if(result.Properties.Contains("displayName"))
                                row["FullName"] = result.Properties["displayName"][0].ToString();

                            // Telephone number
                            if(result.Properties.Contains("telephoneNumber"))
                                row["Phone"] = result.Properties["telephoneNumber"][0].ToString();

                            // Mobile phone
                            if(result.Properties.Contains("mobile"))
                                row["Mobile"] = result.Properties["mobile"][0].ToString();

                            // Email addresss (and format it)
                            if(result.Properties.Contains("mail"))
                                if(result.Properties["mail"][0].ToString() != "") {
                                    string email = result.Properties["mail"][0].ToString();
                                    row["Email"] = "<a href=\"mailto:" + email + "\" title=\"Send mail to " + email + "\">" + email + "</a>";
                                }

                            // Office location
                            if(result.Properties.Contains("physicalDeliveryOfficeName"))
                                row["Office"] = result.Properties["physicalDeliveryOfficeName"][0].ToString();

                            // Department
                            if(result.Properties.Contains("department"))
                                row["Department"] = result.Properties["department"][0].ToString();

                            // If there is actually something to display, create a new table row.
                            if(row["Phone"] != "" || row["Mobile"] != "" || row["Email"] != "" || row["Office"] != "" || row["Department"] != "") {
                                tblPeople.Rows.Add(row);
                            }
                        }
                       
                        // instantiate a new DataSet object that
                        DataSet dataSet = new DataSet();
                        dataSet.Tables.Add(tblPeople);

                        // set the data source for the grid to the people table
                        gvSearchResult.DataSource = dataSet.Tables["People"];
                        gvSearchResult.DataBind();

                        lblSearchStatus.Visible = true;
                        lblSearchStatus.Text = tblPeople.Rows.Count.ToString() + " matches found.";
                    } else {
                        lblSearchStatus.Visible = true;
                        lblSearchStatus.Text = "No matches found...";
                    }
                }
            }
        }
    }

    Monday, February 20, 2006 5:04 PM

All replies

  • User1354132231 posted

    Hello

    I'm in the middle of trying to build an "AD phone book", and this being my first try at asp.net, I have a few questions that I hope some of you might be able to help with:

    1. Is it correct, that PageSize equals the max size of the result set?
    2. Is there a way to make asp cache the search result, so the domain controller won't be to bother by all the lookups, and also to speed up searching?
    3. I've been trying to make a "more info" button, that when clicked, should result in a lookup in the AD, for additional information about the person (e.g. I could do the search with GC, and then lookup more info with LDAP), however, I've been unable to figure out how to see, what button was clicked (there is a "more info" button in each row). I small hint would make my day!
    4. I have also had a hard time figuring out how to make my GridView control sort the search result. I would basically like to be able to sort each column alphabetically. Help me out :)

    Thanks and best regards, Egil.


    Resultsets larger than the PageSize will be broken into a number of pages.  Each of these pages will be returned when the PageSize is greater than 0.  As an example, if I had 2000 results, and I have a PageSize = 500, I will get 4 pages returned to me for 2000 results.  I still get them all and it is seamless to the consumer (2000 results and you can't tell I used paging).

    However, if I set a PageSize of 0 (which turns off paging support), then most likely I will only 1000 results because the results exceed the most that can be returned without using paging.  This is controlled by the MaxPageSize LDAP query policy which is by default 1000.

    In terms of caching, the answer is yes, but this is an architectural decision as well.  You can simply cache the DataSet or DTO and return it instead.  However, if you cache very large objects, this can drain performance as well, so you might have to decide here which is worse - performing the search, or caching a ton.  There is definitely a trade off.

    As for the last two questions... I hate to give you bad information if things changed in 2.0.  There used to be a DataGrid event that you had to plug that would tell you which button was clicked in the event arguments.  If you take a look in the Data Presentation Forum, I am sure this is in there including the sorting.  Once you have the data, this is just a data formatting question.

    Finally, there was a function that I had around here called FindUsers that would do the search and optionally cache it as well.  You might take a look at it and see what you can mine from it.
    Wednesday, February 22, 2006 11:48 AM
  • User1540266618 posted
    Hi dunnry, thanks for taking the time to reply to my post. Great to get a few things cleared up, I'll give the Data Presentation Forum and the FindUsers post a look. Thanks again.
    Wednesday, February 22, 2006 2:48 PM