You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebForms C#调用独立类DataReader遇空引用错误求助

问题根源与解决方案

直接错误原因

你在页面代码中仅声明了ProjectName.DBReader db;变量,但从未实例化该对象,导致调用db.SqlReader()时db为null,触发Object reference not set to an instance of an object异常。


第一步:修复页面空引用问题

在使用db前必须先创建实例,同时优化错误处理逻辑:

<!DOCTYPE html>
<script runat="server">
    ProjectName.DBReader db;
    string projectName;

    protected void Page_Load(object sender, EventArgs e)
    {
        // 实例化DBReader对象
        db = new ProjectName.DBReader();
        LoadProjects();
    }

    public void LoadProjects()
    {
        string query = @"SELECT * FROM projects where project_type = 3";
        string debugMsg = "";

        SqlDataReader reader = db.SqlReader(query, ref debugMsg);

        if(reader != null)
        {
            try
            {
                while (reader.Read())
                {
                    // 数据处理逻辑
                }
            }
            finally
            {
                // 关闭Reader时,连接会自动关闭(依赖CommandBehavior.CloseConnection)
                reader.Close();
            }
        }
        else
        {
            // 展示错误信息
            Response.Write($"查询出错:{debugMsg}");
        }
    }
</script>

第二步:优化DBReader类的隐患

你的DBReader类存在资源释放不彻底、错误信息无法传递、连接字符串校验缺失等问题,修改后的版本如下:

namespace ProjectName
{
    public class DBReader
    {
        private readonly string _connectionString;

        public DBReader()
        {
            // 提前校验连接字符串,避免后续隐藏异常
            var connStringSettings = ConfigurationManager.ConnectionStrings["database"];
            if(connStringSettings == null || string.IsNullOrEmpty(connStringSettings.ConnectionString))
            {
                throw new InvalidOperationException("未找到有效的数据库连接字符串");
            }
            _connectionString = connStringSettings.ConnectionString;
        }

        // 使用ref参数传递错误信息,确保外部能获取异常内容
        public SqlDataReader SqlReader(string sql, ref string retDebug)
        {
            try
            {
                var conn = new SqlConnection(_connectionString);
                conn.Open();

                var cmd = new SqlCommand(sql, conn);
                cmd.CommandType = CommandType.Text;
                cmd.CommandTimeout = 180;

                // CommandBehavior.CloseConnection:关闭Reader时自动关闭连接
                return cmd.ExecuteReader(CommandBehavior.CloseConnection);
            }
            catch (SqlException ex)
            {
                retDebug = $"SQL异常:{ex.Message}";
                return null;
            }
            catch (Exception ex)
            {
                retDebug = $"系统异常:{ex.Message}";
                return null;
            }
        }
    }
}

关键优化说明

  1. 参数传递修正:将retDebug改为ref参数,确保外部能接收到错误信息(原代码为值传递,修改无法同步到外部)。
  2. 资源释放逻辑:通过CommandBehavior.CloseConnection让调用方关闭Reader时自动释放连接,避免连接池耗尽;注意不能用using包裹连接,否则连接会提前关闭导致Reader无法读取数据。
  3. 连接字符串校验:在构造函数中提前检查连接字符串有效性,避免后续执行时出现隐藏空引用。
  4. 复用性增强:如果想省去实例化步骤,可将DBReader改为静态类,调用时直接使用DBReader.SqlReader(...)。

内容的提问来源于stack exchange,提问作者rlatmfrl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 00:01:06