解决ASP.NET Web API 2中Object cannot be cast from DBNull错误(不修改数据库)
解决“Object cannot be cast from DBNull to other types”错误
问题根源
你的代码直接对数据库中可能为NULL的列(Mobile、Date)执行类型转换,当列值为NULL时,sdr.GetValue()返回DBNull.Value,直接调用ToString()、Convert.ToDateTime()等方法会触发类型转换错误。
解决方案
不需要修改数据库,只需调整代码处理DBNull的情况,步骤如下:
调整实体类属性为可空类型
确保TestClass的Mobile和Date属性支持空值,匹配数据库允许为空的设置:public class TestClass { public int UserId { get; set; } public string Name { get; set; } public string? Mobile { get; set; } // 可空字符串 public int Access { get; set; } public DateTime? Date { get; set; } // 可空DateTime类型 }读取数据时判断DBNull值
使用SqlDataReader.IsDBNull()方法检查列值是否为NULL,再进行对应处理。同时建议用using语句自动释放数据库资源:public IHttpActionResult Get() { List<TestClass> draft = new List<TestClass>(); string mainconn = ConfigurationManager.ConnectionStrings["myconn"].ConnectionString; // using语句自动释放连接,避免资源泄漏 using (SqlConnection sqlconn = new SqlConnection(mainconn)) { string sqlquery = "Select * From tblTest"; sqlconn.Open(); using (SqlCommand sqlcomm = new SqlCommand(sqlquery, sqlconn)) using (SqlDataReader sdr = sqlcomm.ExecuteReader()) { while (sdr.Read()) { draft.Add(new TestClass() { UserId = Convert.ToInt32(sdr.GetValue(0)), Name = sdr.GetValue(1).ToString(), // 检查Mobile列是否为NULL,是则赋值null,否则转字符串 Mobile = sdr.IsDBNull(2) ? null : sdr.GetValue(2).ToString(), Access = Convert.ToInt32(sdr.GetValue(3)), // 检查Date列是否为NULL,是则赋值null,否则转DateTime Date = sdr.IsDBNull(4) ? null : Convert.ToDateTime(sdr.GetValue(4)) }); } } } return Ok(draft); }更健壮的写法:使用列名而非索引
用列名代替索引读取数据,避免因数据库表结构调整(列顺序变化)导致代码出错:public IHttpActionResult Get() { List<TestClass> draft = new List<TestClass>(); string mainconn = ConfigurationManager.ConnectionStrings["myconn"].ConnectionString; using (SqlConnection sqlconn = new SqlConnection(mainconn)) { string sqlquery = "Select * From tblTest"; sqlconn.Open(); using (SqlCommand sqlcomm = new SqlCommand(sqlquery, sqlconn)) using (SqlDataReader sdr = sqlcomm.ExecuteReader()) { // 获取列名对应的索引 int userIdOrdinal = sdr.GetOrdinal("UserId"); int nameOrdinal = sdr.GetOrdinal("Name"); int mobileOrdinal = sdr.GetOrdinal("Mobile"); int accessOrdinal = sdr.GetOrdinal("Access"); int dateOrdinal = sdr.GetOrdinal("Date"); while (sdr.Read()) { draft.Add(new TestClass() { UserId = sdr.GetInt32(userIdOrdinal), Name = sdr.GetString(nameOrdinal), Mobile = sdr.IsDBNull(mobileOrdinal) ? null : sdr.GetString(mobileOrdinal), Access = sdr.GetInt32(accessOrdinal), Date = sdr.IsDBNull(dateOrdinal) ? null : sdr.GetDateTime(dateOrdinal) }); } } } return Ok(draft); }
内容的提问来源于stack exchange,提问作者user19613128
相关产品推荐
相关产品推荐

