I am saving an image file in a SQL Server column (datatype varbinary(max)). Code to save file in database:
Stream fs = imgUpload.PostedFile.InputStream;
BinaryReader br = new BinaryReader(fs);
Byte[] bytes = br.ReadBytes((Int32)fs.Length);
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["connectionString"].ToString());
conn.Open();
using (SqlCommand cmd = new SqlCommand("update tbEHUsers set photo=#binaryValue where UserID="+Session["UserID"].ToString(), conn))
{
cmd.Parameters.Add("#binaryValue", SqlDbType.VarBinary, -1).Value = bytes;
cmd.ExecuteNonQuery();
}
conn.Close();
Get image data from SQL Server:
SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["connectionString"].ToString());
con.Open();
SqlCommand CMD = new SqlCommand("SELECT Photo from tbEHUsers where UserID=" + Session["UserID"], con);
SqlDataReader rdr = CMD.ExecuteReader();
byte[] imgArray = null;
while (rdr.Read())
{
imgArray = (byte[])rdr["Photo"];
}
File.WriteAllBytes("D:\\Test12345.jpg", imgArray);
Original size of file which I uploaded was 858KB however after retrieving from database and saving it again using File.WriteAllBytes method it increases to 859KB. Now when I try to open this file I get 'corrupted file error'. The byte array size was same both the time while saving and retrieving.
What am I doing wrong here??
When using FileUpload.PostedFile you need to reset the InputStream to start from the beginning again. So add the following line on top of your code:
imgUpload.PostedFile.InputStream.Seek(0, SeekOrigin.Begin);
Related
I am trying to retrieve a picture stored in MS SQL Server database. The type of the column is image. My code is:
try
{
SqlConnection con = new SqlConnection(Properties.Settings.Default.ConnectionString);
SqlCommand cmd = new SqlCommand(string.Empty, con);
cmd.CommandText = "select Picture from Person";
con.Open();
SqlDataReader dataReader = cmd.ExecuteReader();
dataReader.Read();
byte[] image = new byte[10000];
long len = dataReader.GetBytes(0, 0, image, 0, 10000);
using (MemoryStream stream = new MemoryStream(image))
{
stream.Seek(0, SeekOrigin.Begin);
pictureBox1.Image = Image.FromStream(stream);
}
con.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
I am continuously getting ArgumentException as Parameter is not valid when I set the pictureBox1.Image property. I tried all the available solutions on the Internet but all in vain.
You are always using a 10000 byte array even if the image is smaller (or larger). Don't manually create the byte[], the DataReader can provide the entire byte array if you ask for it.
byte[] image = reader.GetFieldValue<byte[]>(0);
If you are not using .NET 4.5 you can just ask for the field and cast it manually.
byte[] image = (byte[])reader.GetValue(0);
However the fact that you are only using the first column from the first row you don't need a DataReader at all, just use ExecuteScalar() instead. (I also am cleaning up your code to use proper using statements and switched your ex.Message to ex.ToString() to provide more info in the error dialog).
try
{
using(SqlConnection con = new SqlConnection(Properties.Settings.Default.ConnectionString))
using(SqlCommand cmd = new SqlCommand(string.Empty, con))
{
cmd.CommandText = "select Picture from Person";
con.Open();
byte[] image = (byte[])cmd.ExecuteScalar();
using (MemoryStream stream = new MemoryStream(image))
{
pictureBox1.Image = Image.FromStream(stream);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
Try this :
SqlConnection con = new SqlConnection(Properties.Settings.Default.ConnectionString);
SqlCommand cmd = new SqlCommand(string.Empty, con);
cmd.CommandText = "select Picture from Person";
con.Open();
SqlDataReader dataReader = cmd.ExecuteReader();
dataReader.Read();
byte[] image = new byte[10000];
long len = dataReader.GetBytes(0, 0, image, 0, 10000);
using (MemoryStream mStream = new MemoryStream(image))
{
pictureBox1.Image = Image.FromStream(mStream);
}
can any one suggest a code to insert word document to SQL database and download it from SQL database.(code should be visual studio c# windows application)
Thank you
Read the word document as byte array and store that as blob data in database.
For downloading read the byte array and stream the output as file with .doc extension
Assume you have this table schema and you are using local sql db:
CREATE TABLE [FileTable1]
(
[filePath] VARCHAR(100),
[data] VARBINARY(MAX)
)
Here is the code to Insert:
static void InsertFile(string filename)
{
SqlConnection conn = new SqlConnection("Server=(localdb)\\v11.0 ; Initial Catalog = {your db name}; Integrated Security = SSPI");
SqlCommand cmd = new SqlCommand("INSERT INTO FileTable1 VALUES (#filePath, #data)", conn);
cmd.Parameters.AddWithValue("#filePath", Path.GetFileName(filename));
cmd.Parameters.Add("#data", SqlDbType.VarBinary, -1).Value = File.ReadAllBytes(filename);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
here is the code to insert:
string filetoInsert = #"C:\Temp\Test1.docx";
InsertFile(filetoInsert);
you can then retrieve it from database, like so:
static byte[] ReadFile(string filename)
{
SqlConnection conn= new SqlConnection("Server=(localdb)\\v11.0 ; Initial Catalog = {your db name}; Integrated Security = SSPI");
SqlCommand cmd = new SqlCommand("SELECT * FROM FileTable1 WHERE filePath=#filePath", conn);
cmd.Parameters.AddWithValue("#filePath", filename);
conn.Open();
SqlDataReader rdr = cmd.ExecuteReader();
rdr.Read();
MemoryStream ms = new MemoryStream();
long startIndex= 0;
const int readSize= 256;
while (true)
{
byte[] buffer = new byte[readSize];
long bytesRead= rdr.GetBytes(1, startIndex, buffer, 0, readSize);
ms.Write(buffer, 0, (int)bytesRead);
startIndex += bytesRead;
if (bytesRead != readSize) break;
}
conn.Close();
byte[] byteArr = ms.ToArray();
ms.Dispose();
return byteArr;
}
once you retrieve the data from db, you can save it somewhere in a temp location or in your designated location.
string fileToRetrieve = #"Test1.docx";
var fileRetrieved = RetrieveFile(fileToRetrieve);
string tempFile = #"C:\file\path\Retrived.docx";
File.WriteAllBytes(tempFile, fileRetrieved);
Open the file as a MemoryStream (of bytes). Save the memorystream to your SQL table - to a column defined as VARBINARY(MAX). to restore the file, do the same in reverse. Plenty of info for these steps on the internet
I have the following method i am using to save an object into an SQL Server CE database. I am now stuck on how to get the record back out.
public void SaveRecord(LabRecord _labrecord)
{
try
{
conn = new SqlCeConnection(_connectionString);
conn.Open();
MemoryStream memStream = new MemoryStream();
StreamWriter sw = new StreamWriter(memStream);
sw.Write(_labrecord);
SqlCeCommand sqlCmd = new SqlCeCommand("INSERT INTO LabTransactions([TrasactionType], [CAM], [TransactionObject]) VALUES ('ResultTest', 1234, #Image)", conn);
sqlCmd.Parameters.Add("#Image", SqlDbType.Image, Int32.MaxValue);
sqlCmd.Parameters["#Image"].Value = memStream.GetBuffer();
sqlCmd.ExecuteNonQuery();
}
finally
{
conn.Close();
}
}
Update
I am looking to make another class that returns a specific record.
public LabRecord getRecord(int transactionId)
{
LabRecord returnRecord = null;
try
{
conn = new SqlCeConnection(_connectionString);
conn.Open();
//.... Get the record
}
finally
{
conn.Close();
}
return returnRecord;
}
I think the problem most likely lies in the fact that the size of the #Image parameter is being set to Int32.MaxValue
Set it instead to the length of the image byte stream:
byte[] imgBytes = memStream.GetBuffer();
sqlCmd.Parameters.Add("#Image", SqlDbType.Image, imgBytes.Length);
sqlCmd.Parameters["#Image"].Value = imgBytes;
Here's an excerpt from this example (modified for your question) of how you might go about retrieving the image:
// Get the record
SqlCeCommand cmd = new SqlCeCommand("Select [TransactionObject] From LabTransactions Where [CAM] = 1234", conn);
conn.Open();
SqlCeDataReader sdr = cmd.ExecuteReader();
byte[] imgByteData = Convert.ToByte(sdr.Item("Picture"));
Bitmap bitmap = new Bitmap(new System.IO.MemoryStream(imgByteData));
I have a database in MYSQL Server. There's a table store an Image with its info. That image's data type is Mediumblob. I need to read it and store in a byte[] but I don't know how to do that.Anyone have a solution for this case? Tks so much :)
Regards.
Looking at the examples from this article on MySQL website, you should be able to handle the data like this:
To store the image:
MySql.Data.MySqlClient.MySqlConnection conn;
MySql.Data.MySqlClient.MySqlCommand cmd;
// initialize "conn" and "cmd" here
FileStream fs = new FileStream(#"c:\image.png", FileMode.Open, FileAccess.Read);
FileSize = fs.Length;
byte[] rawData = new byte[FileSize];
fs.Read(rawData, 0, FileSize);
fs.Close();
conn.Open();
string SQL = "INSERT INTO file VALUES(NULL, #FileSize, #File)";
cmd.Connection = conn;
cmd.CommandText = SQL;
cmd.Parameters.AddWithValue("#FileSize", FileSize);
cmd.Parameters.AddWithValue("#File", rawData);
cmd.ExecuteNonQuery();
conn.Close();
And to read it:
MySql.Data.MySqlClient.MySqlConnection conn;
MySql.Data.MySqlClient.MySqlCommand cmd;
MySql.Data.MySqlClient.MySqlDataReader myData;
// initialize connection and query here...
myData = cmd.ExecuteReader();
if (!myData.HasRows)
throw new Exception("There are no BLOBs to save");
myData.Read();
int FileSize = myData.GetUInt32(myData.GetOrdinal("file_size"));
byte[] rawData = new byte[FileSize];
myData.GetBytes(myData.GetOrdinal("file"), 0, rawData, 0, (int)FileSize);
FileStream fs = new FileStream(#"C:\newfile.png", FileMode.OpenOrCreate, FileAccess.Write);
fs.Write(rawData, 0, (int)FileSize);
fs.Close();
This code shows how to save the image into a file (and assumes it is stored in the PNG format) but you could do whatever you want with the data then...
I'm using these following codes to save picturebox image to database. just i need some code to load picturebox image from database to picturebox.
DialogResult dr = openFileDialog1.ShowDialog();
switch (dr)
{
case DialogResult.Cancel:
break;
case DialogResult.OK:
pictureBox1.Image = Image.FromFile(openFileDialog1.FileName);
sql = new SqlConnection(#"Data Source=PC-PC\PC;Initial Catalog=Test;Integrated Security=True");
cmd = new SqlCommand();
cmd.Connection = sql;
cmd.CommandText = ("insert [Entry] ([Image]) values (#Image)");
MemoryStream stream = new MemoryStream();
pictureBox1.Image.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] image = stream.ToArray();
cmd.Parameters.AddWithValue("#Image", image);
try
{
sql.Open();
cmd.ExecuteNonQuery();
}
finally
{
sql.Close();
}
break;
here there are both code: http://www.codeproject.com/Articles/25956/Sending-Receiving-PictureBox-Image-in-C-To-From-Mi
button2_Click is used to Retrieve the Image:
SqlConnection connect = new SqlConnection
("Server=.;database=PictureDb;integrated security=true");
SqlCommand command = new SqlCommand
("select fldPic from tblUsers where fldCode=1", connect);
//for retrieving the image field in SQL SERVER EXPRESS
//Database you should first bring
//that image in DataList or DataTable
//then add the content to the byte[] array.
//That's ALL!
SqlDataAdapter dp = new SqlDataAdapter(command);
DataSet ds = new DataSet("MyImages");
byte[] MyData = new byte[0];
dp.Fill(ds, "MyImages");
DataRow myRow;
myRow = ds.Tables["MyImages"].Rows[0];
MyData = (byte[])myRow["fldPic"];
MemoryStream stream = new MemoryStream(MyData);
//With the code below, you are in fact converting the byte array of image
//to the real image.
pictureBox2.Image = Image.FromStream(stream);