Hello again,

I have a method:

public static void GetStudents(DropDownList list, Label lbl)
    {
        SqlConnection conn = new SqlConnection(Config.DbConnectionString);
        SqlCommand cmd = new SqlCommand("GetStudentsToDDL", conn);
        cmd.CommandType = CommandType.StoredProcedure;
        SqlDataReader reader;
        try
        {
            conn.Open();
            reader = cmd.ExecuteReader();
            while (reader.Read())
            {
                ListItem item = new ListItem();
                item.Text = reader["StudentName"].ToString() + " " + reader["StudentFamilyname"].ToString();
                item.Value = reader["StudentID"].ToString();
                list.Items.Add(item);
            }
            reader.Close();
        }
        catch (Exception ex)
        {
            lbl.Text = ex.Message;
            Utilities.LogError(ex);
            throw;
        }
        finally
        {
            conn.Close();
        }
    }
ddlStudents.DataSource = CatalogAccess.GetStudents(ddlStudents, lbl);
ddlStudents.DataBind();

Says: Error 3 Cannot implicitly convert type 'void' to 'object'

Where's the problem?

Dani AI

Generated

Short diagnosis: the original compile error happened because your call expected a return value while the method returned void was right. You either call a void method that fills the DropDownList (no assignment), or make the method return a data object (DataTable, List<T>, etc.) and bind that from the page.

About the IndexOutOfRangeException: StudentName you see now: that means the result set does not have a column with that name. Common causes are a typo/alias mismatch in the stored procedure, multiple resultsets, or accidentally consuming the reader incorrectly (for example, calling a loop with reader.Read() and then calling DataTable.Load(reader) inside the loop). To verify, after ExecuteReader() inspect the column names with reader.GetName(i) or run the stored procedure in SSMS to see the exact column names and order.

Recommended fixes:

  • Keep data access and UI separate. Have a method that returns a DataTable (or List of a small DTO), using using to dispose connection/command/reader. Load the reader into the DataTable once (or use SqlDataAdapter.Fill) — do not mix reader.Read() and tbl.Load(reader) in the same loop.
  • Bind the returned table on the page: set DataTextField and DataValueField to the correct column names, set DataSource to the table, then call DataBind().
  • If you prefer the method to populate the DropDownList directly, make it void and call it without assigning its return.

Example pattern (conceptual):

var table = CatalogAccess.GetStudentsTable();   // returns DataTable
ddlStudents.DataTextField = "FullName";        // actual column from SP
ddlStudents.DataValueField = "StudentID";
ddlStudents.DataSource = table;
ddlStudents.DataBind();

Quick checklist: do not instantiate new controls inside the data method, use using blocks for DB objects, confirm stored-proc column names, and avoid adding items manually when you plan to use DataSource/DataBind.

Recommended Answers

All 5 Replies

public static void GetStudents ...

Your method returns nothing (void) yet your other code expects it to be returning something.

public static void GetStudents ...

Your method returns nothing (void) yet your other code expects it to be returning something.

OK. I know what the 'void' means. I just don't understand what I should return? This method just suppose to connect to DB and populate dropdownlist.

You don't have to pass anything back. You are already adding to the dropdown list in the code, so setting the datasource isn't needed. Get rid of the assignment:

CatalogAccess.GetStudents(ddlStudents, lbl);

should be all you need.

this approach doesn't work for me. I've improved the method:

public void GetStudents()
    {
        SqlConnection conn = new SqlConnection(Config.DbConnectionString);
        SqlCommand cmd = new SqlCommand("GetStudentsToDDL", conn);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandText = "GetStudentsToDDL";
        SqlDataReader reader;
        try
        {
            conn.Open();
            reader = cmd.ExecuteReader();
            while (reader.Read())
            {
                DropDownList ddlStudents=new DropDownList();
                ListItem item = new ListItem();
                item.Text = reader["StudentName"].ToString() + " " + reader["StudentFamilyname"].ToString();
                item.Value = reader["StudentID"].ToString();
                ddlStudents.Items.Add(item);
            }
            reader.Close();
        }
        catch (Exception ex)
        {
            Label lbl=new Label();
            lbl.Text = ex.Message;
            Utilities.LogError(ex);
            throw;
        }
        finally
        {
            conn.Close();
        }
    }

And the code in WebUserControl

CatalogAccess ca = new CatalogAccess();
        ddlStudents.DataSource = ca.GetStudents();
        ddlStudents.DataBind();

I am still getting the Error Cannot implicitly convert type 'void' to 'object'

Hi again. I've rewritten my method and now it returns DataTable

public static DataTable GetStudents(DropDownList ddlStudents, Label lbl)
    {
        SqlConnection conn = new SqlConnection(Config.DbConnectionString);
        SqlCommand cmd = new SqlCommand("GetStudentsToDDL", conn);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandText = "GetStudentsToDDL";
        DataTable tbl = new DataTable();
        SqlDataReader reader;
        
        try
        {
            conn.Open();
            reader = cmd.ExecuteReader();
            
            while (reader.Read())
            {
                 ListItem item = new ListItem();
                 item.Text = reader["StudentName"].ToString()+" " + reader["StudentFamilyname"].ToString();
                item.Value = reader["StudentID"].ToString();
                ddlStudents.Items.Add(item);
                tbl.Load(reader);
            }
            
            reader.Close();
        }
        catch (Exception ex)
        {
            lbl.Text = ex.Message;
            Utilities.LogError(ex);
            throw;
        }
        finally
        {
            conn.Close();
        }
        return tbl;
    }

Another error: System.IndexOutOfRangeException: StudentName

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.