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; } } } }
关键优化说明
- 参数传递修正:将
retDebug改为ref参数,确保外部能接收到错误信息(原代码为值传递,修改无法同步到外部)。 - 资源释放逻辑:通过
CommandBehavior.CloseConnection让调用方关闭Reader时自动释放连接,避免连接池耗尽;注意不能用using包裹连接,否则连接会提前关闭导致Reader无法读取数据。 - 连接字符串校验:在构造函数中提前检查连接字符串有效性,避免后续执行时出现隐藏空引用。
- 复用性增强:如果想省去实例化步骤,可将DBReader改为静态类,调用时直接使用
DBReader.SqlReader(...)。
内容的提问来源于stack exchange,提问作者rlatmfrl
相关产品推荐
相关产品推荐

