Wednesday, March 7, 2012

Cannot Convet Sql image to Byte[]

I have followed many examples found on this site, but still get an invalid cast execption when I attempt to run code below. the exception is thrown when I try to convert the sql image to a byte[] in the download section of the code.


//
// sqlUploadImage
//
this.sqlUploadImage.CommandText = "INSERT INTO Image_Table (Description, Type, Lenth, DocName) VALUES (@.Description," +
" @.Type, @.Length, @.DocName)";
this.sqlUploadImage.Connection = this.sqlConnection2;
this.sqlUploadImage.Parameters.Add(new System.Data.SqlClient.SqlParameter("@.Description", System.Data.SqlDbType.VarChar, 50, "Description"));
this.sqlUploadImage.Parameters.Add(new System.Data.SqlClient.SqlParameter("@.Type", System.Data.SqlDbType.VarChar, 50, "Type"));
this.sqlUploadImage.Parameters.Add(new System.Data.SqlClient.SqlParameter("@.Length", System.Data.SqlDbType.Int, 4, "Lenth"));
this.sqlUploadImage.Parameters.Add(new System.Data.SqlClient.SqlParameter("@.DocName", System.Data.SqlDbType.VarChar, 50, "DocName"));
this.sqlUploadImage.Parameters.Add(new System.Data.SqlClient.SqlParameter("@.Image", System.Data.SqlDbType.Image, 16, "ImgField"));
this.Button2.Click += new System.EventHandler(this.Button2_Click);
//
// sqlDownLoadImage
//
this.sqlDownLoadImage.CommandText = "SELECT Image_Table.* FROM Image_Table";
this.sqlDownLoadImage.Connection = this.sqlConnection2;

//upload file
private void Button1_Click(object sender, System.EventArgs e)
{
//Get the filename of the pdf file to be uploaded.
string strFilename = File1.PostedFile.FileName.Substring(File1.PostedFile.FileName.LastIndexOf("\\") +1);

//Get the file type
string strFileType = File1.PostedFile.ContentType;

//Get the file size
int intImageSize = File1.PostedFile.ContentLength;

// Reads the Image
Stream ImageStream = File1.PostedFile.InputStream;

byte[] ImageContent = new byte[intImageSize + 1];
int intStatus = 0;
intStatus = ImageStream.Read(ImageContent, 0, intImageSize);

//Response.Write(strFilename.ToString());
//Response.Write("<br>Image Type: " + strFileType.ToString());
//Response.Write("<br>Image Size: "+intImageSize.ToString());

this.sqlUploadImage.Parameters["@.Description"].Value = strFilename;
this.sqlUploadImage.Parameters["@.Type"].Value = strFileType;
this.sqlUploadImage.Parameters["@.Length"].Value = intImageSize;
this.sqlUploadImage.Parameters["@.DocName"].Value = "TestPDF";
this.sqlUploadImage.Parameters["@.Image"].Value = ImageContent;

try
{
this.sqlConnection2.Open();
this.sqlUploadImage.ExecuteNonQuery();

this.Label2.Text = "File Uploaded Successfully";
this.Button2.Visible = true;
}
catch(SqlException ex)
{
Response.Write(ex.ToString());
}
finally
{
this.sqlConnection2.Close();
}
}

//download file
private void Button2_Click(object sender, System.EventArgs e)
{
try
{
this.sqlConnection2.Open();
SqlDataReader r = this.sqlDownLoadImage.ExecuteReader(CommandBehavior.CloseConnection);

if(r.Read())
{

Response.ContentType = r["Type"].ToString();
byte[] image = (byte[])r["ImgField"];
Response.BinaryWrite(image);
}
}
catch(SqlException ex)
{
Response.Write(ex.ToString());
}
finally
{
this.sqlConnection2.Close();
}
}

I am somewhat confused because the INSERT statement for your upload process only contains 4 parameters (even though 5 parameters are specified). So my guess is that the image is not gettng into the database (and is therefore NULL), and that is why you are getting the exception on the download portion?

Terri|||Thanks for the reply, but there are 5 parameters.

I have double check the database and all information is there for the upload and all information is valid.

The problem is on the download.

byte[] image = (byte[])r["ImgField"];

throughs an invalid cast.... I have found many articles using this exact cast.|||HOly cow, I see it now.

only 4 parameters.

let me see if i change itl|||ok fixed my insert string.

Now I have verifity there is nothing being uploaded to hte ImgField... it is DBNULL.|||Why are you adding 1 to the image file size when dimensioning the byte array? I thought the size of the byte array should match the file size?


byte[] ImageContent = new byte[intImageSize];

Terri|||Yes, fixed that also.

Ok it uploads now.

BUT, when I download I get just the binary information to output. And it doesn't output on in the browser but in a new webform.

any ideas?

Updated code here


//
// sqlConnection2
//
this.sqlConnection2.ConnectionString = ((string)(configurationAppSettings.GetValue("sqlConnection2.ConnectionString", typeof(string))));
//
// sqlDownLoadImage
//
this.sqlDownLoadImage.CommandText = "SELECT Image_Table.* FROM Image_Table";
this.sqlDownLoadImage.Connection = this.sqlConnection2;
//
// sqlCommand1
//
this.sqlCommand1.CommandText = "SELECT ImgField, Type FROM Image_Table WHERE (ImageID = 1)";
this.sqlCommand1.Connection = this.sqlConnection2;
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

//upload file
private void Button1_Click(object sender, System.EventArgs e)
{
//Get the filename of the pdf file to be uploaded.
string strFilename = File1.PostedFile.FileName.Substring(File1.PostedFile.FileName.LastIndexOf("\\") +1);

//Get the file type
string strFileType = File1.PostedFile.ContentType;

//Get the file size
int intImageSize = File1.PostedFile.ContentLength;

//Reads teh image
Stream imgStream = File1.PostedFile.InputStream;

byte[] ImageContent = new byte[intImageSize];
int intStatus = imgStream.Read(ImageContent, 0, intImageSize);

//Response.Write(strFilename.ToString());
//Response.Write("<br>Image Type: " + strFileType.ToString());
//Response.Write("<br>Image Size: "+intImageSize.ToString());

SqlCommand sqlUpload = new SqlCommand("INSERT INTO Image_Table(Description, ImgField, Type, Lenth, DocName)" +
"VALUES (@.Description, @.Image, @.Type, @.Length, @.DocName)", this.sqlConnection2);

SqlParameter param0 = new SqlParameter("@.Description", SqlDbType.VarChar, 50);
param0.Value = strFilename;
sqlUpload.Parameters.Add( param0 );

SqlParameter param1 = new SqlParameter("@.Image", SqlDbType.Image);
param1.Value = ImageContent;
sqlUpload.Parameters.Add( param1 );

SqlParameter param2 = new SqlParameter("@.Type", SqlDbType.VarChar, 50);
param2.Value = strFileType;
sqlUpload.Parameters.Add( param2 );

SqlParameter param3 = new SqlParameter("@.Length", SqlDbType.Int);
param3.Value = intImageSize;
sqlUpload.Parameters.Add( param3 );

SqlParameter param4 = new SqlParameter("@.DocName", SqlDbType.VarChar, 50);
param4.Value = "Test PDF";
sqlUpload.Parameters.Add( param4 );

try
{
this.sqlConnection2.Open();
sqlUpload.ExecuteNonQuery();

this.Label2.Text = "File Uploaded Successfully";
this.Button2.Visible = true;
}
catch(SqlException ex)
{
Response.Write(ex.ToString());
}
finally
{
this.sqlConnection2.Close();
}
}

//download file
private void Button2_Click(object sender, System.EventArgs e)
{
try
{
this.sqlConnection2.Open();
SqlDataReader r = this.sqlDownLoadImage.ExecuteReader(CommandBehavior.CloseConnection);

if(r.Read())
{
Response.ContentType = r["Type"].ToString();
Response.BinaryWrite((byte[])r["ImgField"]);
Response.
}
}
catch(SqlException ex)
{
Response.Write(ex.ToString());
}
finally
{
this.sqlConnection2.Close();
}
}

|||Ok, if I am working with photos, jpeg, gif etc.. the above code works great. But I need to store and view pdf files and this code is not working for that type of application/pdf

please any ideas?|||I believe you need to use the Response object's AddHeader method in order to get that to work for you. I don't have any direct experience with that, but this post might help:view post 463798

Terri|||Thanks,

I am getting the same results it won't open in a broswer window when I use inline. I would like this to happen, but does this mean i must save the file first to a spot before I can view it.

If that is true, will it be easier for me to just store the pdf's in a file structure on teh server and have teh database store a path to it?

Thanks|||I am having a similar problem

i am trying to use the example at:
http://aspalliance.com/articleViewer.aspx?aId=140

got the upload working

the download is another story though.
when i use the following code i get a conversion issue

Response.BinaryWrite(myDataReader.Item("PersonImage"))

it says that with option strict on, i can not make an implicit conversion from system.object to a 1-dimensional array of Byte.

this is driving me crazy and all the above is way beyond me - as a beginner in this arena|||Instead of this:


Response.BinaryWrite(myDataReader.Item("PersonImage"))

try this:

Response.BinaryWrite(CType(myDataReader.Item("PersonImage"), Byte()))

That should explicitly do the conversion to a byte array.

Terri|||

Terri is a Stud!!!!!!!

That worked FOR ME

No comments:

Post a Comment