Retrieving an image from SQL Server - c#

I wrote this code but faced an exception that said: Parameter Not Valid.
string connstr = #"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\db.mdf;Integrated Security=True;User Instance=True";
SqlConnection conn = new SqlConnection();
conn.ConnectionString = connstr;
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT * FROM tbl";
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
DataTable dt = new DataTable();
da.Fill(dt);
byte[] barrImg = (byte[])dt.Rows[1]["image"];
MemoryStream mstream = new MemoryStream();
mstream.Write(barrImg, 0, barrImg.Length);
mstream.Seek(0, SeekOrigin.Begin);
img.Image = Image.FromStream(mstream);
mstream.Close();
The exception is:
Parameter is not valid.
in the Image.FromStream line of code.
I checked the value that in datatable was assigned to the image field. It was System.Byte[]. I traced the code. Every thing seems to be correct. But it does not work.
I searched around this problem. Another site preferred to set mstream.Position = 0. But that does not work.
I stored my image by this code.If it maybe that I saved this wrong!
string connstr = #"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\db.mdf;Integrated Security=True;User Instance=True";
SqlConnection conn = new SqlConnection();
conn.ConnectionString = connstr;
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
string sql = "INSERT INTO tbl (name, family, image) VALUES ('name', 'family', '{0}')";
sql = string.Format(sql, Image.FromFile("test.jpg"));
cmd.CommandText = sql;
cmd.ExecuteNonQuery();
conn.Close();
new code to save the image:
public byte[] ReadFile(string sPath)
{
byte[] data = null;
FileInfo fInfo = new FileInfo(sPath);
long numBytes = fInfo.Length;
FileStream fStream = new FileStream(sPath, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fStream);
data = br.ReadBytes((int)numBytes);
return data;
}
and :
private void cmdSave_Click(object sender, EventArgs e)
{
string connstr = #"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\db.mdf;Integrated Security=True;User Instance=True";
byte[] imageData = ReadFile("test.jpg");
SqlConnection CN = new SqlConnection(connstr);
string qry = "insert into tbl (name, family, image) VALUES ('name', 'family', '{0}')";
qry = string.Format(qry, imageData);
SqlCommand SqlCom = new SqlCommand(qry, CN);
CN.Open();
SqlCom.ExecuteNonQuery();
CN.Close();
}

Um, that's not going to work.
Your code that "stores" the image, well, doesn't really do what you think it does.
It is putting the value "test.jpg" into the image field. That isn't the binary image data; only the filename.
So, when you go to pull it back out the Image.FromStream(mstream) call is going to blow chunks because the value "test.jpg" is not an image.. ergo: the parameter is not valid
Here is an example of what you need to be doing to actually put the image into the database:
http://www.codeproject.com/Articles/21208/Store-or-Save-images-in-SQL-Server

You close the stream then try to pull an image from the stream, hence the error "cannot access a closed stream."
Try swapping the order of your last two lines:
img.Image = Image.FromStream(mstream);
mstream.Close();

using (MemoryStream mstream = new MemoryStream((byte[])dt.Rows[1]["image"]))
{
img.Image = Image.FromStream(mstream);
}
Would simplify things. I suspect your problem would be you need to call mStream.Flush() after write and before the seek.
To put an image in to a database, one way is.
string connstr = #"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\db.mdf;Integrated Security=True;User Instance=True";
using(SqlConnection conn = new SqlConnection(connstr))
{
using (SqlCommand comm = new SqlCommand(conn))
{
comm.CommandText = "INSERT INTO tbl (name, family, image) VALUES (#name,#family,#Content)";
comm.Parameters.Add(new SqlParameter("name",DbType.String,"Fred"));
comm.Parameters.Add(new SqlParameter("family",DbType.String,"Flintstone"));
using(FileStream fs = new FileStream("FredWilmaBamBamAndDino.jpg",FileMode.Open,FileAccess.Read))
{
comm.Parameters.Add(new SqlParameter("content",DbType.Image,fs));
}
cmd.ExecuteNonQuery();
}
}
Notice it puts the content of teh file in the database. Since in the case of a jpg that content is most definitely not a string, use a parameterised query. Which youi should be doing anyway, develop a good habit.
You also need to suss out using, your code was leaking resources all over the place.

Related

Why does my drop down list display “System.Data.DataRowView” instead of real values?

I tried to get data in a drop down list and it's not working. I don't understand what's the problem.
string connString = #" Data Source=(LocalDB)\v11.0;AttachDbFilename='C:\Users\oshri\Documents\Stock scores.mdf';Integrated Security=True;Connect Timeout=30";
string queryLecturer = "select name_student from student";
SqlConnection conn = new SqlConnection(connString);
//SqlCommand cmdL = new SqlCommand(queryLecturer, conn);
conn.Open();
//SqlCommand SQLCommand = new SqlCommand();
//cmdL.CommandType = CommandType.Text;
//SQLCommand.CommandText = queryLecturer;
//conn.Close();
SqlDataAdapter adapter = new SqlDataAdapter(queryLecturer, conn);
adapter.Fill(subjects);
DropDownListID.DataSource = subjects;
DropDownListID.DataBind();
DropDownListID.DataBind();
conn.Close();
You are assigning a DataSet containing DataRowView items to your drop down. Your drop down (is it a System.Windows.Forms.ComboBox?) is not smart enough to extract the real values from this DataSet. Instead, use a SqlDataReader to read your string values and add them to a list that you can use as data source for your drop down.
string connString = #"Data Source=...";
string queryLecturer = "select name_student from student";
using (var conn = new SqlConnection(connString))
using (var cmd = new SqlCommand(queryLecturer)) {
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader()) {
var list = new List<string>();
while (reader.Read()) {
list.Add(reader.GetString(0)); // 0 is the column index.
}
DropDownListID.DataSource = list;
}
}
The using statements automatically close the connection and dispose resources at the end of the statement blocks. They do so even if the statement blocks are left prematurely because of an exception or because of a break or return statement.

c# FromStream(stream) invalid parameter?

First the method preEntities() inserts a new record into the Entities table. One of the inserted values is an image. The data type for this column in the visual studio database is 'image'.
The method loadPanel() is supposed to take the image from every single record in the table (WHERE TYPE = OBSTACLE) and make a picturebox with that image. However there is an error in the FromStream() method: "INVALID PARAMETER"; I put a comment where the error showed up. I searched for previously asked questions about this error but I didn't find anything yet that helped me :(
private void preEntities() {
string constring = "Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename="
+ "|DataDirectory|\\DonaldJump.mdf;Integrated Security=True;Connect Timeout=30";
SqlConnection con = new SqlConnection(constring);
con.Open();
byte[] image = ImageToByteArray(Properties.Resources.Pipe);
string q = "INSERT INTO dbo.Entities(Name, Type, Image, Width, Height) VALUES('Pipe','Obstacle','" + image + "','97','150')";
SqlCommand cmd = new SqlCommand(q, con);
cmd.ExecuteNonQuery();
}
private byte[] ImageToByteArray(System.Drawing.Image imageIn) {
using (var ms = new MemoryStream()) {
imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
return ms.ToArray();
}
}
private void loadPanel() {
string constring = "Data Source (LocalDB)\\MSSQLLocalDB;AttachDbFilename="
+ "|DataDirectory|\\DonaldJump.mdf;Integrated Security=True;Connect Timeout=30";
SqlConnection con = new SqlConnection(constring);
con.Open();
string q = "SELECT * FROM dbo.Entities WHERE Type='obstacle';";
DataTable dt = new DataTable();
using (var command = new SqlCommand(q, con)) {
using (SqlDataReader dr = command.ExecuteReader()) {
dt.Load(dr);
}
}
foreach (DataRow dr in dt.Rows) {
PictureBox pb = new PictureBox();
pb.Location = new Point(10, 10);
pb.Size = new Size(50, 50);
pb.SizeMode = PictureBoxSizeMode.Zoom;
byte[] img = dr.Field<byte[]>("Image");
MemoryStream mstream = new MemoryStream(img);
pb.Image = Image.FromStream(mstream); //ERROR IS HERE!!!!!!!!!!!!!!!!!!!!!
pb.Name = dr.Field<string>("Name");
pb.Parent = flowLayoutPanel1;
pb.Click += pbClick;
pb.BringToFront();
}
}
You can't concatenate a string with a byte array. The result will be something like 'Pipe','Obstacle','System.Byte[]','97','150'.
You need to use SqlParameter.
First create the query and then add parameters to your command :
string q = "INSERT INTO dbo.Entities(Name, Type, Image, Width, Height) VALUES('Pipe','Obstacle',#image,'97','150')";
SqlCommand cmd = new SqlCommand(q, con);
cmd.Parameters.AddWithValue("image", img);

I try to make Qr code application ( generated and then save it on DataBase) , but have some errors with my program code

I am getting this two errors
'SqlConnection' does not contain a definition for 'Parameters' and no extension
method 'Parameters' accepting a first argument of type 'SqlConnection' could be found (are you missing a using directive or an assembly reference?)
and
'SqlConnection' does not contain a definition for 'ExecuteNonQuery' and no extension method 'ExecuteNonQuery' accepting a first argument of type 'SqlConnection' could be found (are you missing a using directive or an assembly reference?)
Source Error:
SqlConnection con1;
con1 = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\User1\Documents\ESDB.mdf;Integrated Security=True;Connect Timeout=30");
con1.Open();
string qry = "Insert into QRCODES(Image) VALUES(#PIC)";
SqlConnection cmd = new SqlConnection(qry);
MemoryStream STREAM = new MemoryStream();
pictureBox1.Image.Save(STREAM,System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] pic = STREAM.ToArray();
cmd.Parameters.AddWithValue("#PIC", pic);
cmd.ExecuteNonQuery();
cmd.Dispose();
con1.Close();
Now when i re-build my code with
SqlCommand cmd = new SqlCommand
I get new error ( warning ) and it say :
An unhandled exception of type 'System.NullReferenceException' occurred in WindowsFormsApplication1.exe
Additional information: Object reference not set to an instance of an object.
You are using two SqlConnection objects. It should be SqlCommand:
SqlConnection con1;
con1 = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\User1\Documents\ESDB.mdf;Integrated Security=True;Connect Timeout=30");
con1.Open();
string qry = "Insert into QRCODES(Image) VALUES(#PIC)";
SqlCommand cmd = new SqlCommand(qry);
^^^^^^^^^^ ^^^^^^^^^^
MemoryStream STREAM = new MemoryStream();
pictureBox1.Image.Save(STREAM, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] pic = STREAM.ToArray();
cmd.Parameters.AddWithValue("#PIC", pic);
cmd.ExecuteNonQuery();
cmd.Dispose();
con1.Close();
Also be careful with that code, because you're using commands and connections and you're not disposing them. It can lead you to memory leaks and several problems.
Maybe you should think in refactor to something like this:
using (SqlConnection con1 = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\User1\Documents\ESDB.mdf;Integrated Security=True;Connect Timeout=30"))
{
con1.Open();
string qry = "Insert into QRCODES(Image) VALUES(#PIC)";
using (SqlCommand cmd = new SqlCommand(qry))
{
using (MemoryStream STREAM = new MemoryStream())
{
pictureBox1.Image.Save(STREAM, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] pic = STREAM.ToArray();
cmd.Parameters.AddWithValue("#PIC", pic);
cmd.ExecuteNonQuery();
con1.Close();
}
}
}
UPDATE:
Your problem, as the error says, is that the command and the connection are not associated. This should work:
using (SqlConnection con1 = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\User1\Documents\ESDB.mdf;Integrated Security=True;Connect Timeout=30"))
{
con1.Open();
string qry = "Insert into QRCODES(Image) VALUES(#PIC)";
using (SqlCommand cmd = con1.CreateCommand()) //associate the connection to the command
{
cmd.CommandText = qry; //assign the command text to the command.
using (var STREAM = new MemoryStream())
{
pictureBox1.Image.Save(STREAM, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] pic = STREAM.ToArray();
cmd.Parameters.AddWithValue("#PIC", pic);
cmd.ExecuteNonQuery();
con1.Close();
}
}
}

ExecuteScalar: Connection property has not been initialized. SQL Server Connection

I wrote this code to read the images stored in SQL Server database however I got this error:
ExecuteScalar: Connection property has not been initialized.
Since I already initialized the connection, I am not sure what the problem is.
SqlConnection myConnection = null;
try
{
myConnection = new SqlConnection("Data Source=Source; Initial Catalog=Database; user ID=Test; Password=Test");
SqlCommand myCommand = new SqlCommand ("SELECT imagedata FROM Database , myConnection");
myConnection.Open();
// Get the image from the database.
byte[] imagedata = (byte[])myCommand.ExecuteScalar();
if (imagedata != null)
{
return image;
}
else
{
return null;
}
}
finally
{
myConnection.Close();
}
You have put both your Select statement and your connection in double quotes ("). i.e you didn't specify the SqlCommand's Connection property actually. Change your SqlCommand from this:
SqlCommand myCommand = new SqlCommand ("SELECT imagedata FROM Database , myConnection");
To this:
SqlCommand myCommand = new SqlCommand ("SELECT imagedata FROM Database" , myConnection);
Or like this:
SqlCommand myCommand = new SqlCommand("SELECT imagedata FROM Database");
myCommand.Connection = myConnection;

Adapter not loading anything with SQLite C#

I use this code and SQLite says "Data Source cannot be empty. Use :memory: to open an in-memory database"
here is my code
string dbfile = new System.IO.FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).DirectoryName + "\\m23.db";
string sql;
DateTime dt = DateTime.Now;
SQLiteConnection connection = new SQLiteConnection("datasource="+ dbfile);
SQLiteDataAdapter adapter = new SQLiteDataAdapter("select * from p_posts", connection);
DataSet data = new DataSet();
adapter.Fill(data); // <<< here i get the error
SQLiteCommand cmd = new SQLiteCommand();
cmd.CommandType = CommandType.TableDirect;
cmd.Connection = connection;
connection.Open();
Any help is apreciated ,
Cheers !
Try using
SQLiteConnection connection = new SQLiteConnection("Data Source=" + dbfile);
The examples I've seen use "Data Source" instead of "datasource".
To avoid such parameter syntax issues you might also consider using SQLiteConnectionStringBuilder
SQLiteConnectionStringBuilder con = new SQLiteConnectionStringBuilder();
con.DataSource = dbfile;

Categories