无效试图调用时阅读的读者被关闭? [英] Invalid attempt to call Read when reader is closed?

查看:137
本文介绍了无效试图调用时阅读的读者被关闭?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我运行一个 DbDataReader 上查询,以便从他们是否已经连接到特定提交一个DropDownList删除项目,和我不断收到一个错误告诉我阅读器是封闭的。不明白为什么被看作我的读者此处关闭。我在想什么?

 保护无效的Page_Load(对象发件人,EventArgs的发送)
{    字符串x =的Request.QueryString [SUBID];
    字符串的connectionString = System.Configuration.ConfigurationManager。
        。的ConnectionStrings [MyConnectionString]的ConnectionString;
    字符串displayQuery =选择的CustName,CustAdd,CustCity,CustState,+
        CustZip从客户WHERE子ID =+ X;
    字符串broQuery =SELECT FROM的EntityType WHERE经纪人= SUBID+ X;
    字符串ddlQuery =SELECT从产品编号SubmissionProducts+
        WHE​​RE SubmissionId =+ X;
    使用(SqlConnection的displayConn =新的SqlConnection(的connectionString))
    {
        displayConn.Open();
        的SqlCommand DlistCmd =新的SqlCommand(ddlQuery,displayConn);        使用(SqlDataReader的Ddldr = DlistCmd.ExecuteReader())
        {
            而(Ddldr.Read())
            {                开关(Ddldr.GetInt32(0))
                {
                    情况1:
                        DdlProductList.Items.RemoveAt(1);
                        打破;
                    案例2:
                        DdlProductList.Items.RemoveAt(2);
                        打破;
                    案例3:
                        DdlProductList.Items.RemoveAt(3);
                        打破;
                    情况4:
                        DdlProductList.Items.RemoveAt(4);
                        打破;
                    情况5:
                        DdlProductList.Items.RemoveAt(5);
                        打破;
                    情况6:
                        DdlProductList.Items.RemoveAt(6);
                        打破;
                    案例7:
                        DdlProductList.Items.RemoveAt(7);
                        打破;
                    默认:
                        打破;
                }
                Ddldr.Close();
            }        }


解决方案

不要叫 Ddldr.Close(); ,尤其是里面的。这种方式是在做第一次迭代,关闭读取器和第二次迭​​代当然booom作为读者被关闭。在使用语句将照顾它。只要从code删除此行。

所以:

 使用(SqlDataReader的Ddldr = DlistCmd.ExecuteReader())
{
    而(Ddldr.Read())
    {
        开关(Ddldr.GetInt32(0))
        {
            ...您的案件在这里
            默认:
                打破;
        }
    }
}

另外,下面几行:

 字符串x =的Request.QueryString [SUBID];
字符串displayQuery =选择的CustName,CustAdd,CustCity,CustState,CustZip从客户WHERE子ID =+ X;
字符串broQuery =SELECT FROM的EntityType WHERE经纪人= SUBID+ X;
字符串ddlQuery =SELECT从产品编号WHERE SubmissionProducts = SubmissionId+ X;

臭像一堆s..t的。您应该使用参数化查询和绝对不会写任何code这样或您的应用程序将很容易受到SQL注入攻击。每次你写一个SQL查询时使用字符串连接的闹钟是否响铃告诉你,你做错了。

所以在这里谈到这样做的正确方法:

 保护无效的Page_Load(对象发件人,EventArgs的发送)
{
    字符串x =的Request.QueryString [SUBID];
    字符串的connectionString = System.Configuration.ConfigurationManager.ConnectionStrings [MyConnectionString]的ConnectionString。
    使用(VAR康恩=新的SqlConnection(的connectionString))
    使用(VAR CMD = conn.CreateCommand())
    {
        conn.Open();
        cmd.CommandText =SELECT从产品编号WHERE SubmissionProducts = SubmissionId @SubmissionId;
        cmd.Parameters.AddWithValue(@ SubmissionId,x)的        使用(VAR读卡器= cmd.ExecuteReader())
        {
            而(Ddldr.Read())
            {
                开关(reader.GetInt32(reader.GetOrdinal(产品编号)))
                {
                    ...您的案件在这里
                    默认:
                        打破;
                }
            }        }
    }
}

I'm running a DbDataReader on a query to remove items from a dropdownlist if they are already attached to a specific submission, and I keep getting an error telling me the reader is closed. Can't see why my reader is being seen as closed here. What am I missing?

 protected void Page_Load(object sender, EventArgs e)
{

    string x = Request.QueryString["SubId"];
    string connectionString = System.Configuration.ConfigurationManager.
        ConnectionStrings["MyConnectionString"].ConnectionString;
    string displayQuery = "SELECT CustName, CustAdd, CustCity, CustState, " +
        "CustZip FROM Customer WHERE SubId =" + x;
    string broQuery = "SELECT EntityType FROM Broker WHERE SubId =" + x;
    string ddlQuery = "SELECT ProductId FROM SubmissionProducts " +
        "WHERE SubmissionId =" + x;
    using (SqlConnection displayConn = new SqlConnection(connectionString))
    {
        displayConn.Open();
        SqlCommand DlistCmd = new SqlCommand(ddlQuery, displayConn);

        using (SqlDataReader Ddldr = DlistCmd.ExecuteReader())
        {
            while (Ddldr.Read())
            {

                switch (Ddldr.GetInt32(0))
                {
                    case 1:
                        DdlProductList.Items.RemoveAt(1);
                        break;
                    case 2:
                        DdlProductList.Items.RemoveAt(2);
                        break;
                    case 3:
                        DdlProductList.Items.RemoveAt(3);
                        break;
                    case 4:
                        DdlProductList.Items.RemoveAt(4);
                        break;
                    case 5:
                        DdlProductList.Items.RemoveAt(5);
                        break;
                    case 6:
                        DdlProductList.Items.RemoveAt(6);
                        break;
                    case 7:
                        DdlProductList.Items.RemoveAt(7);
                        break;
                    default:
                        break;
                }
                Ddldr.Close();
            }

        }

解决方案

Don't call Ddldr.Close();, especially inside the while. This way you are doing a first iteration, closing the reader and the second iteration will of course booom as the reader is closed. The using statement will take care of it. Simply remove this line from your code.

So:

using (SqlDataReader Ddldr = DlistCmd.ExecuteReader())
{
    while (Ddldr.Read())
    {
        switch (Ddldr.GetInt32(0))
        {
            ... your cases here
            default:
                break;
        }
    }
}

Also the following lines:

string x = Request.QueryString["SubId"];
string displayQuery = "SELECT CustName, CustAdd, CustCity, CustState, CustZip FROM Customer WHERE SubId =" + x;
string broQuery = "SELECT EntityType FROM Broker WHERE SubId =" + x;
string ddlQuery = "SELECT ProductId FROM SubmissionProducts WHERE SubmissionId =" + x;

stink like a pile of s..t. You should be using parametrized queries and absolutely never write any code like this or your application will be vulnerable to SQL injection. Everytime you use a string concatenation when writing a SQL query an alarm should ring telling you that you are doing it wrong.

So here comes the correct way of doing this:

protected void Page_Load(object sender, EventArgs e)
{
    string x = Request.QueryString["SubId"];
    string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
    using (var conn = new SqlConnection(connectionString))
    using (var cmd = conn.CreateCommand())
    {
        conn.Open();
        cmd.CommandText = "SELECT ProductId FROM SubmissionProducts WHERE SubmissionId = @SubmissionId";
        cmd.Parameters.AddWithValue("@SubmissionId", x)

        using (var reader = cmd.ExecuteReader())
        {
            while (Ddldr.Read())
            {
                switch (reader.GetInt32(reader.GetOrdinal("ProductId")))
                {
                    ... your cases here
                    default:
                        break;
                }
            }

        }
    }
}

这篇关于无效试图调用时阅读的读者被关闭?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆