Asp.net项目中SqlNullValueException异常解决求助
问题分析与解决方案
核心异常原因
触发System.Data.SqlTypes.SqlNullValueException的直接原因是访问了未赋值的Sql类型属性的Value成员。在ASPX页面的按钮点击事件中,你新建了空的UserENT entuser = new UserENT();,但没有将baluser.Login(userid)的返回值赋值给它,导致entuser的所有Sql类型属性(如User_Name、User_ID等)处于Null状态,此时访问.Value就会抛出该异常。
代码中的其他问题
- 登录判断逻辑错误:使用
||(或)判断用户名和密码,应改为&&(且) - 密码赋值错误:
userpass = txtusername.Text.Trim();应该取txtpassword的值 - 未处理
baluser.Login(userid)返回null的情况,无错误提示 - DAL中
while (objSDR.Read())会循环所有结果,最终只保留最后一条数据的赋值(若存储过程返回多条数据)
修正后的代码
1. ASPX页面按钮点击事件修正
protected void btnLogin_Click(object sender, EventArgs e) { #region Server Side Validation String strerr = ""; if (string.IsNullOrEmpty(txtusername.Text.Trim())) { strerr += "请输入用户名<br/>"; } if (string.IsNullOrEmpty(txtpassword.Text.Trim())) { strerr += "请输入密码<br/>"; } if (!string.IsNullOrEmpty(strerr)) { lblMessage.EnableViewState = true; lblMessage.Text = strerr; return; // 验证失败,终止后续逻辑 } #endregion #region Gather Data string username = txtusername.Text.Trim(); string userpass = txtpassword.Text.Trim(); #endregion UserBAL baluser = new UserBAL(); SqlInt32 userid = Convert.ToInt32(txtuserid.Text.Trim()); if (Request.QueryString["User_ID"] == null) { // 接收Login方法返回的实体,而非使用空实体 UserENT entuser = baluser.Login(userid); if (entuser != null) { // 访问Value前先判断是否为Null string dbUserName = entuser.User_Name.IsNull ? "" : entuser.User_Name.Value.ToString().Trim(); string dbPassword = entuser.Password.IsNull ? "" : entuser.Password.Value.ToString().Trim(); // 修正登录判断逻辑:用户名和密码需同时匹配 if (dbUserName == username && dbPassword == userpass) { Response.Redirect("AddSubject.aspx"); } else { lblMessage.Text = "用户名或密码错误"; } } else { lblMessage.Text = "未找到该用户"; } } }
2. DAL代码优化(可选)
public UserENT PR_IP_User_LoginUser(SqlInt32 UserID) { using (SqlConnection objconn = new SqlConnection(ConnectionString)) { objconn.Open(); using (SqlCommand objcmd = objconn.CreateCommand()) { try { objcmd.CommandType = CommandType.StoredProcedure; objcmd.CommandText = "PR_IP_User_LoginUser"; objcmd.Parameters.AddWithValue("@UserID", UserID); UserENT entuser = new UserENT(); using (SqlDataReader objSDR = objcmd.ExecuteReader()) { // 存储过程仅返回单条用户数据,用if替代while if (objSDR.Read()) { int userNameOrdinal = objSDR.GetOrdinal("User_Name"); if (!objSDR.IsDBNull(userNameOrdinal)) { entuser.User_Name = objSDR.GetString(userNameOrdinal).Trim(); } int passwordOrdinal = objSDR.GetOrdinal("Password"); if (!objSDR.IsDBNull(passwordOrdinal)) { entuser.Password = objSDR.GetString(passwordOrdinal).Trim(); } int userIdOrdinal = objSDR.GetOrdinal("User_ID"); if (!objSDR.IsDBNull(userIdOrdinal)) { entuser.User_ID = objSDR.GetInt32(userIdOrdinal); } int contactNoOrdinal = objSDR.GetOrdinal("ContactNo"); if (!objSDR.IsDBNull(contactNoOrdinal)) { entuser.ContactNo = objSDR.GetString(contactNoOrdinal); } int emailIdOrdinal = objSDR.GetOrdinal("Email_ID"); if (!objSDR.IsDBNull(emailIdOrdinal)) { entuser.Email_ID = objSDR.GetString(emailIdOrdinal); } int isAdminOrdinal = objSDR.GetOrdinal("Is_Admin"); if (!objSDR.IsDBNull(isAdminOrdinal)) { entuser.Is_Admin = objSDR.GetBoolean(isAdminOrdinal); } } } return entuser; } catch (Exception e) { Message = e.Message; return null; } } } }
关键注意事项
- 对于
SqlString、SqlInt32等Sql类型,访问Value前必须通过.IsNull判断是否为Null,避免抛出异常 - 接收BAL层返回的实体时,必须使用返回值覆盖空实体,否则操作的是未赋值的空对象
- 登录验证逻辑需同时校验用户名和密码,不能用“或”判断
内容的提问来源于stack exchange,提问作者Vandit Joshi
相关产品推荐
相关产品推荐

