【问题标题】:ASP C# Invalid attempt to call FieldCount when reader is closed阅读器关闭时,ASP C# 尝试调用 FieldCount 无效
【发布时间】:2016-05-12 19:54:27
【问题描述】:

我有一个函数(PopulateStudents),它用数据库的结果填充下拉列表。该函数在两种不同的情况下被调用:当提供带有 id 的查询字符串时,以及在 onselectedindexchanged 事件中。基本上,如果从 URL 中提供了 ID,则获取学生 ID 的数据库记录,其中包含 termID 和 courseID。然后,根据 studentID 填充所有 DDL。

如果 URL 中没有 ID,则用户从 DDL 中选择一个学期。然后根据在学期 DDL 中选择的学期 ID 填充课程 DDL。然后,根据所选课程填充学生 DDL。

问题是,当查询字符串中没有提供 ID 并且用户必须选择学期和课程时,PopulateStudent 函数可以正常工作。在查询字符串中提供 ID 时,PopulateStudents 函数不起作用。该函数抛出一个错误,上面写着Invalid attempt to call FieldCount when reader is closed.我的代码有什么问题?

这是 aspx.cs 文件:

protected void Page_Load(object sender, EventArgs e)
        {

            if (!IsPostBack)
            {
                if (Request.QueryString["id"] != null)
                {
                    GetStudentScores(Convert.ToInt32(Request.QueryString["id"]));

                    string connString;
                    connString = RetrieveConnectionString();

                    SqlConnection conn = new SqlConnection(connString);

                    try
                    {
                        using (conn)
                        {
                            conn.Open();
                            SqlCommand cmd = new SqlCommand("dbo.GetEnrolleeDetails", conn);
                            cmd.Parameters.Add("@enrollmentID", System.Data.SqlDbType.Int);
                            cmd.Parameters["@enrollmentID"].Value = Convert.ToInt32(Request.QueryString["id"]);

                            cmd.CommandType = System.Data.CommandType.StoredProcedure;

                            SqlDataReader reader = cmd.ExecuteReader();
                            reader.Read();

                            int semesterID = Convert.ToInt32(reader["semesterId"]);
                            int courseID = Convert.ToInt32(reader["courseId"]);

                            PopulateCourses(semesterID);
                            PopulateStudents(courseID);

                            DDSemester.SelectedValue = Convert.ToString(semesterID);
                            DDCourse.SelectedValue = Convert.ToString(courseID);
                            DDStudent.SelectedValue = Request.QueryString["ID"];
                        }
                    }
                    catch (Exception err)
                    {
                        lblStatus.Text = err.Message;
                    }
                    finally
                    {
                        conn.Close();
                        conn.Dispose();
                    }
                }
            }
        }

        protected void DDCourse_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (IsPostBack)
            {
                PopulateStudents(Convert.ToInt32(DDCourse.SelectedValue));
            }
        }



        protected void DDStudent_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (IsPostBack)
            {
                GetStudentScores(Convert.ToInt32(DDStudent.SelectedValue));
            }
        }

        protected void DDSemester_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (IsPostBack)
            {
                PopulateCourses(Convert.ToInt32(DDSemester.SelectedValue));
            }
        }

        private void PopulateCourses(int semesterID)
        {
            string connString;
            connString = RetrieveConnectionString();

            SqlConnection conn = new SqlConnection(connString);

            try
            {
                using (conn)
                {
                    conn.Open();
                    SqlCommand cmd = new SqlCommand("dbo.GetSemesterCourses", conn);
                    cmd.Parameters.Add("@semesterID", System.Data.SqlDbType.Int);
                    cmd.Parameters["@semesterID"].Value = semesterID;

                    cmd.CommandType = System.Data.CommandType.StoredProcedure;

                    DDCourse.DataSource = cmd.ExecuteReader();
                    DDCourse.DataTextField = "courseName";
                    DDCourse.DataValueField = "courseId";
                    DDCourse.DataBind();
                }
            }
            catch (Exception err)
            {
                lblStatus.Text = err.Message;
            }
            finally
            {
                conn.Close();
                conn.Dispose();
            }
        }

        private void PopulateStudents(int courseID)
        {
            string connString;
            connString = RetrieveConnectionString();

            SqlConnection conn = new SqlConnection(connString);

            try
            {
                using (conn)
                {
                    conn.Open();
                    SqlCommand cmd = new SqlCommand("dbo.CourseEnrollment", conn);
                    cmd.Parameters.Add("@courseId", System.Data.SqlDbType.Int);
                    cmd.Parameters["@courseId"].Value = courseID;

                    cmd.CommandType = System.Data.CommandType.StoredProcedure;

                    DDStudent.DataSource = cmd.ExecuteReader();
                    DDStudent.DataTextField = "fullName";
                    DDStudent.DataValueField = "enrollmentId";
                    this.DataBind();
                }
            }
            catch (Exception err)
            {
                lblStatus.Text = err.Message;
            }
            finally
            {
                conn.Close();
                conn.Dispose();
            }
        }

这里是asp:

<asp:Label ID="Label1" runat="server" Text="Semester:"></asp:Label>
    <asp:DropDownList ID="DDSemester" runat="server" AutoPostBack="True" AppendDataBoundItems="true" DataSourceID="SqlDataSource1" DataTextField="semesterName" DataValueField="semesterId" OnSelectedIndexChanged="DDSemester_SelectedIndexChanged">       
                <asp:ListItem Text="Select a Semester"></asp:ListItem>
    </asp:DropDownList><br />

    <asp:Label ID="Label15" runat="server" Text="Course:"></asp:Label>
    <asp:DropDownList ID="DDCourse" runat="server" AutoPostBack="True" AppendDataBoundItems="true" OnSelectedIndexChanged="DDCourse_SelectedIndexChanged">
        <asp:ListItem Text="Select a Course"></asp:ListItem>
    </asp:DropDownList><br />

    <asp:Label ID="Label16" runat="server" Text="Student"></asp:Label>
    <asp:DropDownList ID="DDStudent" runat="server" AutoPostBack="true" AppendDataBoundItems="true" OnSelectedIndexChanged="DDStudent_SelectedIndexChanged">
        <asp:ListItem Text="Select a Student"></asp:ListItem>
    </asp:DropDownList><br />

感谢您的宝贵时间。

【问题讨论】:

  • 您应该只在 using 语句的范围内创建连接,例如using (var conn = new SqlConnection(connString) {。这样,您就不需要任何手动关闭/处置调用。可能不是解决方案,但通过简化代码应该会有所帮助。这同样适用于任何 Reader 对象和 SqlCommands。基本上,任何你可以在这里使用 using 语句的地方,都可以这样做:)

标签: c# asp.net


【解决方案1】:

实际上,我没有注意到 PopulateCourses 和 PopulateStudents 函数之间的一个区别。在课程中,我使用了 DDCourse.DataBind(),在学生中我使用了 this.DataBind()。

在 populatestudents 函数中,将 this.DataBind() 更改为 DDStudent.DataBind() 解决了我的问题。

【讨论】:

    猜你喜欢
    • 2011-03-28
    • 1970-01-01
    • 1970-01-01
    • 2021-08-29
    • 1970-01-01
    • 1970-01-01
    • 2013-12-26
    • 1970-01-01
    • 2011-08-26
    相关资源
    最近更新 更多