Unable to read SqlFileStream data - c#

I want to read Filestream column form Sql database. After reading I want to show the file content in a TextBox. In case of .txt file it is working fine but in other type like pfd or doc it is not readable.
Here is the code:
SqlConnection objSqlCon = new SqlConnection(constr);
objSqlCon.Open();
SqlTransaction objSqlTran = objSqlCon.BeginTransaction();
SqlCommand objSqlCmd = new SqlCommand("_p_CV_Download", objSqlCon, objSqlTran);
objSqlCmd.CommandType = CommandType.StoredProcedure;
SqlParameter objSqlParam1 = new SqlParameter("#Branch", SqlDbType.NVarChar);
objSqlParam1.Value = Session["Branch"].ToString();
objSqlCmd.Parameters.Add(objSqlParam1);
SqlParameter objSqlParam2 = new SqlParameter("#Doc_No", SqlDbType.VarChar);
objSqlParam2.Value = (dataItem["Doc_No"].FindControl("DocNoLabel") as Label).Text;
objSqlCmd.Parameters.Add(objSqlParam2);
string path = string.Empty;
string fileType = string.Empty;
SqlDataReader sdr;
using (sdr = objSqlCmd.ExecuteReader())
{
while (sdr.Read())
{
path = sdr[0].ToString();
fileType = sdr[1].ToString();
}
}
objSqlCmd = new SqlCommand("SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()", objSqlCon, objSqlTran);
byte[] objContext = (byte[])objSqlCmd.ExecuteScalar();
SqlFileStream objSqlFileStream = new SqlFileStream(path, objContext, FileAccess.Read, FileOptions.SequentialScan, 0);
byte[] buffer = new byte[(int)objSqlFileStream.Length];
objSqlFileStream.Read(buffer, 0, buffer.Length);
string results = System.Text.Encoding.ASCII.GetString(buffer);
ListBox1.Items.Add(results);
objSqlFileStream.Close();
objSqlTran.Commit();

Related

Deserialize binary array from database C#

I am trying to save and retrieve a file to and from a database. I am serializing the object ans saving it as binary. However, when trying to deserialize I get the error that the input stream is not a valid binary format. I tried several solutions and this is what I've put together so far:
public void saveFile(string filename, string file, object o)
{
byte[] myFile;
if (o != null)
{
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, o);
myFile= ms.ToArray();
}
String insert = "INSERT INTO user_files(FileName, Username, File) VALUES ('myfile','noname','"+ myFile + "')";
MySqlCommand command = new MySqlCommand(insert, connection);
try
{
connection.Open();
command.ExecuteNonQuery();
}
catch
{
MessageBox.Show("Sorry, something went wrong");
}
finally
{ connection.Close(); }
}
And here is the Load
public TrafficMonitor LoadFile(string user, string filename)
{
TrafficMonitor obj = null;
byte[] myFile = null;
DataTable dt = new DataTable();
MySqlDataAdapter getCommand = new MySqlDataAdapter("Select File from user_files where Username='noname' and filename='myfile'" , connection);
try
{
connection.Open();
getCommand.Fill(dt);
foreach (DataRow row in dt.Rows)
{
myFile= (byte[])row["File"];
}
MemoryStream memStream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(myFile, 0, myFile.Length);
memStream.Seek(0, SeekOrigin.Begin);
obj = (TrafficMonitor)binForm.Deserialize(memStream);
}
catch { MessageBox.Show("Sorry, something went wrong"); }
finally { connection.Close(); }
return obj;
}
Here is how I inserted binary data to MySQL:
byte[] imgBuffer = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
MySqlCommand query = new MySqlCommand();
query.Connection = _connection;
query.CommandText = "INSERT INTO Photos(id,img) VALUES(?id,?img)";
var id = Guid.NewGuid();
query.Parameters.Add("?id", MySqlDbType.Binary).Value = id.ToByteArray();
query.Parameters.Add("?img", MySqlDbType.Blob).Value = imgBuffer;
query.ExecuteNonQuery();
And how I read binary data from MySQL:
MySqlCommand query = new MySqlCommand();
query.Connection = _connection;
query.CommandText = "SELECT * FROM Photos WHERE id=#ID";
query.Parameters.Add("#id", MySqlDbType.Binary).Value = guid.ToByteArray();
using (MySqlDataReader reader = query.ExecuteReader())
{
if (reader.Read())
{
Guid id = reader.GetGuid(0);
byte[] imgBuffer = (byte[])reader.GetValue(1);
}
}

how to retrieve image from database into picturebox in c#

private void view_Load(object sender, EventArgs e)
{
try
{
SqlConnection con = new SqlConnection();
con.ConnectionString = "Data Source=SOFT;Initial Catalog=Dev01;Integrated Security=True";
con.Open();
//Retrieve BLOB from database into DataSet.
SqlDataReader myReader = null;
SqlCommand cmd = new SqlCommand("select * from empdetails", con);
myReader = cmd.ExecuteReader();
while (myReader.Read())
{
lbl_fname.Text = myReader["firstname"].ToString();
lbl_mname.Text = myReader["middlename"].ToString();
lbl_lname.Text = myReader["lastname"].ToString();
lbl_gender.Text = myReader["gender"].ToString();
lbl_dob.Text = myReader["dob"].ToString();
lbl_qualification.Text = myReader["qualification"].ToString();
lbl_skills.Text = myReader["skills"].ToString();
lbl_userid.Text = myReader["username"].ToString();
lbl_pwd.Text = myReader["password"].ToString();
lbl_cpwd.Text = myReader["confirmpassword"].ToString();
lbl_mno.Text = myReader["mobilenumber"].ToString();
lbl_altmno.Text = myReader["alternativenumber"].ToString();
lbl_email.Text = myReader["email"].ToString();
lbl_presentadd.Text = myReader["presentaddress"].ToString();
lbl_permanentadd.Text = myReader["permanentaddress"].ToString();
}
myReader.Close();
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds, "empdetails");
int c = ds.Tables["empdetails"].Rows.Count;
if (c > 0)
{
//BLOB is read into Byte array, then used to construct MemoryStream,
//then passed to PictureBox.
//SqlCommand cmd1=new SqlCommand("Select photo from empdetails");
Byte[] bytedata = new Byte[0];
bytedata = (Byte[])(ds.Tables["empdetails"].Rows[c - 1]["photo"]);
MemoryStream ms = new MemoryStream(bytedata);
pictureBox1.Image = Image.FromStream(ms,true); //HERE I AM GETTING ERROR
}
con.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I already checked various pages but that didn't solve my problem. I am getting an error only in this part:
"pictureBox1.Image = Image.FromStream(ms,true);"
The data type of your column should be image try
public byte[] ConvertImageToByte(Image image, ImageFormat format)
{
var stream = new MemoryStream();
image.Save(stream, format);
return stream.ToArray();
}
public Image ConvertBytesToImage(object _image)
{
byte[] byteImage = (byte[])(_image);
MemoryStream ms = new MemoryStream(byteImage);
ms.Write(byteImage, 0, byteImage.Length);
Image img = Image.FromStream(ms);
return img;
}
Saving the byte in your database
OpenFileDialog file = new OpenFileDialog();
file.Title = "Please Select the Employee Photo (Dimension 128x128)";
file.Filter = "JPEG Files|*.jpg|Bitmap Files|*.bmp|Gif Files|*.gif|PNG Files|*.png";
file.DefaultExt = "jpg";
file.ShowDialog();
if (!string.IsNullOrEmpty(file.FileName))
{
byte[] bytePhoto = ConvertImageToBytes(Image.FromFile(file.FileName), ImageFormat.Png);
//bytePhoto is the object to save in your database
}
Retrieve the byte and display as image
byte[] bytePhoto = (byte[])ds.Tables["empdetails"].Rows[0]["Photo"];
pictureBox1.Image = ConvertBytesToImage(bytePhoto);

Datareader not reading image value

i am using datareader at page load to read and store database values in variables, my table includes both nvarchar and image type columns. At page load my 5 images value in database is not read by reader but others are perfectly read.
Byte[] img1 = null;
Byte[] img2 = null;
Byte[] img3 = null;
Byte[] img4 = null;
Byte[] img5 = null;
SqlConnection con = new SqlConnection("Data Source=RAJ-PC\\SQLEXPRESS;Initial Catalog=Finder;Integrated Security=True");
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
loadad();
}
}
protected void loadad()
{
SqlCommand cmd = new SqlCommand("sps_addetails", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#ad_id", ad_id);
cmd.Parameters.AddWithValue("#useremail", ses);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
rd_iam.SelectedValue = reader["iam"].ToString();
dd_category.SelectedValue = reader["category"].ToString();
c = Convert.ToInt16(reader["category"].ToString());
dd_subcategory.SelectedValue = reader["subcategory"].ToString();
txt_title.Text = reader["title"].ToString();
txt_description.Text = reader["description"].ToString();
txt_pername.Text = reader["contactname"].ToString();
txt_mobile1.Text = reader["mobile1"].ToString();
txt_mobile2.Text = reader["mobile2"].ToString();
txt_landline1.Text = reader["landline1"].ToString();
txt_landline2.Text = reader["landline2"].ToString();
txt_email1.Text = reader["email1"].ToString();
txt_email2.Text = reader["email2"].ToString();
txt_website.Text = reader["website"].ToString();
dd_country.Text = reader["country"].ToString();
d = Convert.ToInt16(reader["country"].ToString());
dd_state.Text = reader["state"].ToString();
txt_pincode.Text = reader["pincode"].ToString();
txt_address.Text = reader["address"].ToString();
txt_lat.Text = reader["latitude"].ToString();
txt_lon.Text = reader["longitude"].ToString();
img1 = (byte[])reader["image1"];
img2 = (byte[])reader["image2"];
img3 = (byte[])reader["image3"];
img4 = (byte[])reader["image4"];
img5 = (byte[])reader["image5"];
}
con.Close();
}
And stored procedure sps_addetails is
ALTER PROCEDURE [dbo].[sps_addetails]
#ad_id int,
#useremail nvarchar(100)
AS
BEGIN
select * from dbo.tbl_adregister where useremail=#useremail and ad_id=#ad_id
END
aspx
<asp:FileUpload ID="FileUpload1" runat="server" />
update button functionality is (aspx.cs)
Byte[] imgbytes1 = null;
if (FileUpload1.HasFile)
{
HttpPostedFile file1 = FileUpload1.PostedFile;
imgbytes1 = new Byte[file1.ContentLength];
file1.InputStream.Read(imgbytes1, 0, file1.ContentLength);
}
else
{
imgbytes1 = img1;
}
con.Open();
SqlCommand cmd = new SqlCommand("sps_uploadphoto", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#imagedata1", imgbytes1);
cmd.ExecuteNonQuery();
con.Close();
Try first determining the image size, then instantiating the variables, and then use the GetBytes() method:
int index = reader.GetOrdinal("image1");
Int64 size = 0;
try { size = reader.GetBytes(index , 0, null, 0, int.MaxValue); }
catch { size = reader.GetBytes(index, 0, img1, 0, 1); }
img1 = new Byte[size];
reader.GetBytes(index, 0, img1, 0, img1.Length);
... rinse and repeat for images 2 through 5 ...
Let us know if that gets it for you.
Reading image value is different from others...
<img runat="server" id="image1" alt="" src="" height="100" width="100" />
protected void LoadImage1()
{
SqlCommand cmd = new SqlCommand("sps_getimage", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#flag", 1);
cmd.Parameters.AddWithValue("#ad_id", ad_id);
con.Open();
SqlDataReader reader = cmd.ExecuteReader(System.Data.CommandBehavior.SequentialAccess);
if (reader.HasRows)
{
reader.Read();
MemoryStream memory = new MemoryStream();
long startIndex = 0;
const int ChunkSize = 256;
while (true)
{
byte[] buffer = new byte[ChunkSize];
long retrievedBytes = reader.GetBytes(0, startIndex, buffer, 0, ChunkSize);
memory.Write(buffer, 0, (int)retrievedBytes);
startIndex += retrievedBytes;
if (retrievedBytes != ChunkSize)
break;
}
byte[] data = memory.ToArray();
img1 = data;
memory.Dispose();
image1.Src = "data:image/png;base64," + Convert.ToBase64String(data);
}
con.Close();
}

insert query error

My code mainly reads some data from a file and save it on mySql database. I used the insert sql query then used a select sql query to read all data in my database.
When running this code i get the error "Key cannot be null.\r\nParameter name: key} System.Exception {System.ArgumentNullException} "
how do i fix this?
private void bindGrid()//function to connect to database
{
string DocID = User.Identity.Name.ToString();
string connectionString = "server=127.0.0.1;"
+ "database=hospital;"
+ "uid=root;"
+ "pwd=missy3asoola;";
MySqlConnection conn = new MySqlConnection(connectionString);
try
{
conn.Open();
StreamReader objReader = new StreamReader("D:/Senior/WebApplication-metbhdelaXD/WebApplication2/Textfile.txt");
string sLine = "";
ArrayList arrText = new ArrayList();
while (sLine != null)
{
sLine = objReader.ReadLine();
if (sLine != null)
arrText.Add(sLine);
}
objReader.Close();
MySqlCommand cmdread = new MySqlCommand();
cmdread.Connection = conn;
//Defining Mysql Parameters
MySqlParameter Temperature, Pulserate, Timestamp, Doctor_idDoctor, Personal_PatientID;
Temperature = new MySqlParameter();
Pulserate = new MySqlParameter();
Timestamp = new MySqlParameter();
Doctor_idDoctor = new MySqlParameter();
Personal_PatientID = new MySqlParameter();
//Defining Types
Temperature.MySqlDbType = MySqlDbType.Int32;
Pulserate.MySqlDbType = MySqlDbType.Int32;
Timestamp.MySqlDbType = MySqlDbType.Timestamp;
Doctor_idDoctor.MySqlDbType = MySqlDbType.Int32;
Personal_PatientID.MySqlDbType = MySqlDbType.Int32;
//Defining values
Temperature.Value = arrText[0];
Pulserate.Value = arrText[1];
Timestamp.Value = arrText[2];
Doctor_idDoctor.Value = arrText[3];
Personal_PatientID.Value = arrText[4];
//cmdread.Parameters.Clear();
//Adding parameters
cmdread.Parameters.Add(Temperature);
cmdread.Parameters.Add(Pulserate);
cmdread.Parameters.Add(Timestamp);
cmdread.Parameters.Add(Doctor_idDoctor);
cmdread.Parameters.Add(Personal_PatientID);
cmdread.Connection = conn;
cmdread.CommandText = "INSERT INTO medical(Temperature,`Pulse rate`,Timestamp,Doctor_idDoctor,Personal_PatientID)VALUES([#Temperature],[#`Pulse rate`],[#Timestamp],[#Doctor_idDoctor],[#Personal_PatientID]);";
cmdread.CommandType = CommandType.Text;
cmdread.ExecuteNonQuery();
cmdread.Dispose();
string sqlQuery1 = "Select * from medical where Doctor_idDoctor=" + DocID;
MySqlCommand cmdmedical = new MySqlCommand(sqlQuery1, conn);
GridView1.DataSource = cmdmedical.ExecuteReader() ; //ex reader for retrieving
GridView1.DataBind();
conn.Close();
}
catch (Exception ex)
{
Response.Write(ex.StackTrace);
}
}
You are not applying the values from the text file to your parameters. If you don't do this, and your column is a non-nullable column, then you will get an exception, and thats exactly what is happening here.
You should change it to be:
cmdread.Parameters.Add("#Temperature",MySqlDbType.Int32, 5).Value = //value from text file;
cmdread.Parameters.Add("#Pulse rate", MySqlDbType.Int32, 3).Value = //value from text file;
cmdread.Parameters.Add("#Timestamp", MySqlDbType.Timestamp, 15).Value = //value from text file;
cmdread.Parameters.Add("#Doctor_idDoctor", MySqlDbType.Int32, 3).Value = //value from text file;
cmdread.Parameters.Add("#Personal_PatientID", MySqlDbType.Int32, 3).Value = //value from text file;
Also, try not to use spaces in your Column names and parameter names. I would change #Pulse rate to #PulseRate
Furthermore I don't understand why you are giving the return value of cmdread.ExecuteNonQuery() as the DataSource to the GridView. This doesn't seem right.

open word document (saved as binary) from database

I'm making a program with c# and sql server and I have a problem , I hope if anyone help me .
I will but the database on pc and the program will be installed in other PCs , and app pcs' program connected to that database.
the program saving documents (word -excel) as binary ,using this code:
byte[] ReadFile(string sPath)
{
//Initialize byte array with a null value initially.
byte[] data = null;
//Use FileInfo object to get file size.
FileInfo fInfo = new FileInfo(sPath);
long numBytes = fInfo.Length;
//Open FileStream to read file
FileStream fStream = new FileStream(sPath, FileMode.Open, FileAccess.Read);
//Use BinaryReader to read file stream into byte array.
BinaryReader br = new BinaryReader(fStream);
//When you use BinaryReader, you need to supply number of bytes to read from file.
//In this case we want to read entire file. So supplying total number of bytes.
data = br.ReadBytes((int)numBytes);
return data;
}
private void button1_Click(object sender, EventArgs e)
{
string dt = dateTimePicker1.Value.ToShortDateString();
byte[] red = ReadFile(textBox3.Text);
con.Open();
string qry = "insert into documents ([Account no],Name,[Phone number],Date,[Document name],Document,Type) values(#accon,#name,#phone,#date,#docname,#doc,#type)";
//Initialize SqlCommand object for insert.
SqlCommand SqlCom = new SqlCommand(qry, con);
//We are passing Original Image Path and Image byte data as sql parameters.
SqlCom.Parameters.Add(new SqlParameter("#accon", textBox1.Text));
SqlCom.Parameters.Add(new SqlParameter("#name", textBox2.Text));
SqlCom.Parameters.Add(new SqlParameter("#phone", textBox3.Text));
SqlCom.Parameters.Add(new SqlParameter("#date", dt));
SqlCom.Parameters.Add(new SqlParameter("#docname", textBox1.Text));
SqlCom.Parameters.Add(new SqlParameter("#doc", (object)red));
SqlCom.Parameters.Add(new SqlParameter("#type", (object)textBox2.Text));
SqlCom.ExecuteNonQuery();
con.Close();
MessageBox.Show("done");
}
the problem : that I don't know how to retrieve saved documents in database and open it with Microsoft word or Microsoft Excel according to their types.
I want to select specific document form database and open it
Thanks in advance
String connStr = "connection string";
// add here extension that depends on your file type
string fileName = Path.GetTempFileName() + ".doc";
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
// you have to distinguish here which document, I assume that there is an `id` column
cmd.CommandText = "select document from documents where id = #id";
cmd.Parameters.Add("#id", SqlDbType.Int).Value = 1;
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
int size = 1024 * 1024;
byte[] buffer = new byte[size];
int readBytes = 0;
int index = 0;
using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
{
while ((readBytes = (int)dr.GetBytes(0, index, buffer, 0, size)) > 0)
{
fs.Write(buffer, 0, readBytes);
index += readBytes;
}
}
}
}
}
}
// open your file, the proper application will be executed because of proper file extension
Process prc = new Process();
prc.StartInfo.FileName = fileName;
prc.Start();
After you have retrieved your document from the database (or any type of storage you care to use on the server) you should save the document in the windows temporary folder (Path.GetSpecialFolder) and use the Word Interop library to start word (or excel using its own interop library) with the document you just saved.
var temporayFileName = Path.GetRandomFileName();
var temporaryFileStream = File.Open(temporaryFileName, FileMode.Create);
var memoryStream = documentRepository.Get(...);
memoryStream.CopyTo(temporaryFileStream);
// Word App
dynamic wordApp = new Application { Visible = true };
var doc = wordApp.Documents.Add(TemplateName);
templatedDocument.Activate();
(See this document for more information about starting and manipulating word:
http://msdn.microsoft.com/en-us/magazine/ff714583.aspx)
.
The crux is Response.ContentType:
Response.ContentType = "application/vnd.xls"; // for excel
Response.ContentType = "application/ms-word"; // for word
Response.ContentType = "image/jpg";//for jpg images
It is advised to store content type also in database so that your code will be generic and can display/store any type of file
System.Data.SqlClient.SqlDataReader rdr = null;
System.Data.SqlClient.SqlConnection conn = null;
System.Data.SqlClient.SqlCommand selcmd = null;
try
{
conn = new System.Data.SqlClient.SqlConnection(
System.Configuration.ConfigurationManager
.ConnectionStrings["ConnectionString"].ConnectionString);
selcmd = new System.Data.SqlClient.SqlCommand(
"select pic1 from msg where msgid=" + Request.QueryString["imgid"],
conn);
conn.Open();
rdr = selcmd.ExecuteReader();
while (rdr.Read())
{
Response.ContentType = "image/jpg";
Response.BinaryWrite((byte[])rdr["pic1"]);
}
if (rdr != null)
rdr.Close();
}
finally
{
if (conn != null)
conn.Close();
}

Categories