Reputation: 49
I am trying to get back the image that I stored in my database to a picture box
SqlConnection conect = new SqlConnection("Data Source=DESKTOP-R34C6VV\\SQL;Initial Catalog=Restaurant;Integrated Security=True");
conect.Open();
string sql = "select Image from Menu where Name=@name";
SqlCommand cmd = new SqlCommand(sql,conect);
cmd.Parameters.AddWithValue("@name",Invoice_combo.Text);
SqlDataReader read = cmd.ExecuteReader();
read.Read();
if (read.HasRows)
{
byte[] img = ((byte[])read[0]);
if (img == null)
{
pictureBox1.Image = null;
}
else
{
MemoryStream mystream = new MemoryStream(img);
pictureBox1.Image = System.Drawing.Image.FromStream(mystream);
cmd.Dispose();
}
}
else
{
MessageBox.Show("data not available");
}
conect.Close();
but every time I run the program, I get this error on this line
pictureBox1.Image = System.Drawing.Image.FromStream(mystream);
Additional information: Parameter is not valid
When I searched I saw a lot people have this problem but I did not find any solution to the problem; I think it is a problem that happens to beginners.
Can anyone help me with this?
This is my database:
SELECT TOP 1000
[MenuID],
[Category],
[Name],
[Price],
[Image]
FROM
[Restaurant].[dbo].[Menu]
This is the code I used for inserting the image:
OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "png files(*.png)|*.png|jpg files(*.jpg)|*.jpg|ALL files(*.*)|*.*";
if (dialog.ShowDialog() == DialogResult.OK)
{
imglocation = dialog.FileName.ToString();
pictureBox1.ImageLocation = imglocation;
}
on the add button
byte[] image = null;
FileStream stream = new FileStream(imglocation, FileMode.Open, FileAccess.Read);
BinaryReader brs = new BinaryReader(stream);
image = brs.ReadBytes((int)stream.Length);
String str = "Data Source=DESKTOP-R34C6VV\\SQL;Initial Catalog=Restaurant;Integrated Security=True";
String query1 = "Insert into Menu values ( '" + category + "','" + itemname + "'," + price + ",'"+image+"')";
String query2 = "Select MenuID from Menu where Name='" + itemname + "'";
SqlConnection con = null;
con = new SqlConnection(str);
SqlCommand cmd1 = new SqlCommand(query1, con);
SqlCommand cmd2 = new SqlCommand(query2, con);
SqlDataReader MyReader1;
SqlDataReader MyReader2;
con.Open();
MyReader1 = cmd1.ExecuteReader();
con.Close();
MessageBox.Show("Menu added successfully");
Thread.Sleep(2000);
con.Open();
MyReader2 = cmd2.ExecuteReader();
if (MyReader2.Read())
{
String id = System.Convert.ToString(MyReader2.GetInt32(0));
MessageBox.Show(itemname + " was given with MenuID - " + id);
}
con.Close();
Upvotes: 1
Views: 131
Reputation: 236308
Your problem source is the way you save pictures to the database. When you build insert command, here is what will be inserted as the image:
"Insert into Menu values ( 'someCategory','someItemname',42,'System.Byte[]')"
^
When you call ToString()
of the array variable, you will get the type name of your array. So you are not saving any images to the database - you only save same string over and over again.
To fix this issue stop injecting values into your SQL command text. Use SQL parameters instead:
var insertMenuQuery = "INSERT INTO Menu VALUES(@category, @itemName, @price, @image)";
SqlCommand cmd = new SqlCommand(insertMenuQuery, con);
cmd.Parameters.AddWithValue("@category", category);
cmd.Parameters.AddWithValue("@itemName", itemName);
cmd.Parameters.AddWithValue("@price", price);
cmd.Parameters.AddWithValue("@image", image);
// or cmd.Parameters.Add("@image", SqlDbType.VarBinary).Value = image;
This way proper binary data of image will be stored in your database.
NOTE: If images are bigger than 1Mb then consider to use FILESTREAM instead of VARBINARY.
Upvotes: 1
Reputation: 487
The MemoryStream goes out of context after your else path finished. So i guess it would be undefined behaviour to keep using it.
Put your MemoryStream into a class member variable and .Dispose()
it before the end of the application.
Also on a side note, your SqlCommand
is not being disposed of correctly. It only gets disposed of in your else {} block, which is not guaranteed to happen. Put it into a using statement, surrounding everything that needs access to it to guarantee correct disposal.
Upvotes: 1