Spacemancraig
Spacemancraig

Reputation: 1396

what is a more effecient way to create and bind data to a dropdownlist?

I would like to speed up the loading time for an asp.net project I have been working on. One of the dropdownlists is a list of managers that is obtained by comparing a list of employees from a sql table to Active Directory membership.

This is called from Page_Load

        SqlDataSource empDB = (SqlDataSource)Page.Master.FindControl("EmployeeData");
        DataView dv = (DataView)empDB.Select(DataSourceSelectArguments.Empty);

        foreach (DataRowView drv in dv)
        {
            employeeList.Add(new Employee(int.Parse(drv["EMP_ID"].ToString()), drv     ["FULL_NAME"].ToString()));
        }

        managerTest();

        managerDropDownList.DataSource = managerList;
        managerDropDownList.DataTextField = "fullName";
        managerDropDownList.DataValueField = "emp_Id";
        managerDropDownList.DataBind();

The manager test method:

     private void managerTest()
    {

        PrincipalContext domainContext = new PrincipalContext(ContextType.Domain, "the_domain");
        GroupPrincipal managersGroup = GroupPrincipal.FindByIdentity(domainContext, "Managers and Supervisors");
        GroupPrincipal offManagersGroup = GroupPrincipal.FindByIdentity(domainContext, "Office Managers");
        GroupPrincipal executivesGroup = GroupPrincipal.FindByIdentity(domainContext, "Executives");
        GroupPrincipal managers2Group = GroupPrincipal.FindByIdentity(domainContext, "Managers");

        foreach (Employee emp in employeeList)
        {
            UserPrincipal user = UserPrincipal.FindByIdentity(domainContext, emp.fullName);

            if (user != null)
            {
                if (user.IsMemberOf(managersGroup) || user.IsMemberOf(offManagersGroup) || user.IsMemberOf(executivesGroup) || user.IsMemberOf(managers2Group))
                {
                    managerList.Add(emp);
                }
            }
        }

    }

Employee is just a simple class that separates the values for first name, last name and full name.

The issue is that the page loads really slow and there are several controls on the page that postback and causes the postback to take a long time. Is there anything I can do to make this work more efficiently?

Upvotes: 0

Views: 562

Answers (2)

Jupaol
Jupaol

Reputation: 21365

One easy improvement is to load your DropDownList only once, and then rely on the viewstate of the page to mainatin its state, just add the following check to your page: if (!this.IsPostBack)

if (!this.IsPostBack)
{
       SqlDataSource empDB = (SqlDataSource)Page.Master.FindControl("EmployeeData");
        DataView dv = (DataView)empDB.Select(DataSourceSelectArguments.Empty);

        foreach (DataRowView drv in dv)
        {
            employeeList.Add(new Employee(int.Parse(drv["EMP_ID"].ToString()), drv     ["FULL_NAME"].ToString()));
        }

        managerTest();

        managerDropDownList.DataSource = managerList;
        managerDropDownList.DataTextField = "fullName";
        managerDropDownList.DataValueField = "emp_Id";
        managerDropDownList.DataBind();
}

The issue is that the page loads really slow and there are several controls on the page that postback and causes the postback to take a long time

I think that in this case, your page responsiveness would be improved if you use AJAX.

Implementing AJAX without UpdatePanel controls will give you the best UI performance, however you would need to change several things in order to get it work properly

You could use UpdatePanel controls to perform partial updates, the perceived performance will improve because you won't be doing full posts, and the learning curve is really small compared to implementing pure AJAX calls.

The basic steps to do partial page postbacks are:

  • Add a ScriptManager control to the ASPX page (every page using an UpdatePanel MUST have a ScriptManager control)

  • Create an UpdatePanel in your ASPX page, and place in its ContentTemplate all the controls you would like to render as part of the partial postback response

  • Create your server events as you would do in normal full postbacks

You can check the following question for a more detailed use of UpdatePanel controls

How to work with two update panels on same .aspx page

As a reference take a look at the following articles:

Upvotes: 1

aquinas
aquinas

Reputation: 23796

A couple things. First. You should wrap all code you posted in page_load in a if (!IsPostBack). You only need to bind that one time, not every time the page loads. Unless you've turned off viewstate of course.

Second. How often do managers change? Probably not that often. I would recommend storing this in the asp.net Cache. Heck, you might want to do cache it in Global.asax Application_Start. Otherwise, the first person to visit the page will get a performance hit. But that's certainly much better then loading it EVERY TIME someone visits the page. And then you CAN turn off viewstate on the page if you want.

Next. I think the way you are using AD is very inefficient. You are calling it for EVERY employee in a loop. And the only reason why you are doing that is to find out if they are a manager. Instead of doing it that way, find out who all the managers are first. In other words: call AD to get the members of the groups you care about. See this question: get all users from a group in Active Directory for how you can find all the members of an AD group. I suspect that would REALLY help with performance.

Upvotes: 2

Related Questions