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

解决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的情况,步骤如下:

  1. 调整实体类属性为可空类型
    确保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类型
    }
    
  2. 读取数据时判断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);
    }
    
  3. 更健壮的写法:使用列名而非索引
    用列名代替索引读取数据,避免因数据库表结构调整(列顺序变化)导致代码出错:

    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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 21:24:21