如何解决异常:无法将类型为“ System.DBNull”的对象强制转换为类型为“ System.Byte []”

时间:2019-10-17 17:37:06

标签: c# sql .net windows ado.net

我有一个名为tblStaff的表,其中staffImage列具有允许存储Null的Image数据类型。如果用户提供他的照片,则此列会将图像存储为二进制数据,如果他不提供其图像,则它将将存储Null值。如果此列为null值,则ResourceBox文件夹中的图像应显示在pictureBox1中;如果此列具有Binary数据,则应以二进制数据形式存储在此列中的图像应显示在pictureBox1中。

CREATE TABLE tblStaff
(
    staffId int not null identity Primary Key,
    staffName varchar(50) not null,
    staffUserName varchar(25) not null,
    staffPassword varchar(30) not null,
    staffPhone varchar(15) not null,
    staffRole int not null,
    staffStatus tinyint not null,
    **staffImage image**
)

see column name "staffImage" has IMAGE datatype

    ALTER PROC [dbo].[sp_GetStaffImage]
    @staffId varchar(150)
    as
    SELECT Stf.staffImage as 'Image' FROM tblStaff Stf WHERE 
    staffID=@staffId


.
.
.
.

string staffID = Convert.ToString(dataGridViewStaff.Rows[e.RowIndex].Cells["Staff Id"].Value);
..............
.............
..........
...........

SqlConnection con1 = new SqlConnection(cs);
con.Open();
SqlCommand cmd1 = new SqlCommand("sp_GetStaffImage", con);
cmd1.CommandType = CommandType.StoredProcedure;
cmd1.Parameters.AddWithValue("@staffId", staffID);
SqlDataAdapter sda1 = new SqlDataAdapter(cmd1);
DataSet ds = new DataSet();
sda1.Fill(ds);

if(ds.Tables[0].Rows.Count>0)
{
   var img = (byte[])ds.Tables[0].Rows[0][0];

   if (img != Null) //code if the data in column named staffImage is 
                    Binary data then show the image                        
                    in PictureBox1 from the database.
   {

         MemoryStream ms = new MemoryStream(img);
         pictureBox1.Image = new Bitmap(ms);
   }
   else  //code if the data in column named staffImage is Null then show the image in PictureBox1 
           from Resource folder .
   {
       pictureBox1.ImageLocation = "Resources/human.png";
   }

}
con.Close();

通过运行上面的代码,我得到了如下异常: 无法将类型为“ System.DBNull”的对象转换为类型为“ System.Byte []”。

3 个答案:

答案 0 :(得分:1)

  

无法将类型为“ System.DBNull”的对象转换为类型为“ System.Byte []

您的异常源于以下调用:

 var img = (byte[])ds.Tables[0].Rows[0][0];

它是从这里发生的:

 ds.Tables[0].Rows[0][0] // This is DBNull, you can't cast it to byte[]

您正在尝试将System.DBNull投射到System.Byte[],这是行不通的。您需要先检查此值,请参阅下文。

注意:检查此问题的方法比 还多

 var img = ds.Tables[0].Rows[0][0] == DbNull.Value ? null : (byte[])ds.Tables[0].Rows[0][0];

@madreflection建议的替代方法:

 var img = ds.Tables[0].Rows[0].Field<byte[]>(0);

答案 1 :(得分:0)

“无法将类型'System.DBNull'的对象转换为xxx类型”的例外是正确的,并且它也非常简单,因为您尝试从DataRow转换的列值为DbNull。

如果您正在从DataTable中读取行,那么如果该列被键入为可为空的列,则应始终检查DbNull。

例如,代码应如下所示:

 var img = (byte[])(ds.Tables[0].Rows[0][0] == DbNull.Value ? null : ds.Tables[0].Rows[0][0]);

答案 2 :(得分:0)

作为替代答案,并且由于SQL Server中的IMAGE列类型已被弃用,因此可以使用VARBINARY(MAX)NOT NULL作为列类型,并将默认值设置为0x。

这样,您将始终从查询中至少取回字节[0],而不必担心DBNull检查。