So I managed to set-up a simple test page to upload and store image to my database however I am unsure of whether the storage is successful.
Whenever I store the image into my table under the column Image with the datatype Image, this is what is in the new row <Binary data>. Is this <Binary data> the image?
I was expecting it to display the image in '0' and '1' so I can compare the different items stored. But does having "" stored means that my image had been successfully stored?
My website's logic is coded in c#.
And also I had been trying to find sources with examples to how I may retrieve my image for display.
This is my current insert statement
SqlCommand com = new SqlCommand("insert into ImageTotable "
+ "(myphoto,name) values (#photo, #name)", con);
To retrieve the data will this work?
SqlCommand com2 = new SqlCommand("Select * from ImageTotable WHERE userid ='1'", con);
So if I use a datareader to store the selected items, what can I store my image to so that it will display, a label, image button, etc?
And how do I store the image into the variables? For example if I want to store text I would use:
pw = dr["password"].ToString();**
Therefore for images what would it be like?
EDIT: Full button on click event to handle the image strage
protected void Button1_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(#"Data Source=*;Initial Catalog=*;Integrated Security=True");
if (!FileUpload1.HasFile)
{
Label1.Visible = true;
Label1.Text = "Please Select Image File"; //checking if file uploader has no file selected
}
else
{
int length = FileUpload1.PostedFile.ContentLength;
byte[] pic = new byte[length];
FileUpload1.PostedFile.InputStream.Read(pic, 0, length);
try
{
con.Open();
SqlCommand com = new SqlCommand("insert into ImageTotable "
+ "(myphoto,name) values (#photo, #name)", con);
com.Parameters.AddWithValue("#photo", pic);
com.Parameters.AddWithValue("#name", TextBox1.Text);
com.ExecuteNonQuery();
Label1.Visible = true;
Label1.Text = "Image Uploaded Sucessfully"; //after Sucessfully uploaded image
}
finally
{
con.Close();
}
}
}
First, the Image type in Db maps to Byte[] in C#, so you should convert your image into Byte[] before inserting into your database. For retrieving your image from the database, you can use the code:
MemoryStream stream = new MemoryStream(Byte[]);// you can read the image by dataadapter or datareader
System.Drawing.Image img = System.Drawing.Image.FromStream(stream);
Here is a good link: http://www.aspdotnet-suresh.com/2011/01/how-to-insert-images-into-database-and.html and hope it can help you.
here is a complete tutorials.
http://freakzmenia.blogspot.com/2010/11/image-saveretrieve-c-web-sql-server.html
http://freakzmenia.blogspot.com/2010/10/image-saveretrieve-c-windows-form-sql.html
This always helps me. 'fileupload' is the File Upload Control Name.
protected void Upload_btn(object sender, EventArgs e)
{
if (fileupload.HasFile)
{
if (fileupload.PostedFile.FileName == "")
{}
else
{
try
{
int filesize = fileupload.PostedFile.ContentLength;
if (filesize > 819200)
{Label1.Text = "File Size Should be Less than 800Kb";
}
else
{string serverFileName = Path.GetFileName(fileupload.PostedFile.FileName);
byte[] documentBinary = new byte[filesize];
fileupload.PostedFile.InputStream.Read(documentBinary, 0, filesize);
string mainquery = "";
mainquery = "insert into table(DocName,DocSize,Data,ContentType) values(#DocName,#DocSize,#Data,#ContentType)";
con.Open();
SqlCommand files_insert_cmd = new SqlCommand(mainquery,con);
files_insert_cmd.Parameters.AddWithValue("#DocName", serverFileName);
files_insert_cmd.Parameters.AddWithValue("#DocSize",fileupload.PostedFile.ContentLength);
files_insert_cmd.Parameters.AddWithValue("#Data", documentBinary);
files_insert_cmd.Parameters.AddWithValue("#ContentType",fileupload.PostedFile.ContentType);
files_insert_cmd.ExecuteNonQuery();
con.Close();
}
}
catch (Exception e1)
{
Label1.Text = e1.ToString();
Label1.Visible = true;
}
}
}
}
Sorry in advance, because i am about to ask a stupid question. How are you checking data in table? are you right clicking on table and selecting edit top 200 rows
If you do like this, it will always show you as < binary Data > where as if you run sql query you can see actual characters in varbinary(max) column or Image column
Related
private void BTN_Save_Click(object sender, EventArgs e)
{
string DBpath = #"Data Source=.\StudentDB.db;Version=3;";
Bitmap[] PictureBoxesBitmaps = {FirstPictureBitmap, SecondPictureBitmap, ThirdPictureBitmap };
using SQLiteConnection connection = new(DBpath);
using SQLiteCommand cmd = new(DBpath, connection);
connection.Open();
cmd.CommandText = #"DELETE FROM PictureBoxes";
cmd.ExecuteNonQuery();
foreach (Bitmap bitmap in PictureBoxesBitmaps)
{
System.IO.MemoryStream ms = new();
bitmap?.Save(ms, ImageFormat.Png);
byte[] BitmapByteArray = ms.ToArray();
var PictureBox64 = Convert.ToBase64String(BitmapByteArray);
cmd.CommandText = #"INSERT INTO PictureBoxes(Encoded) VALUES('" + PictureBox64 + "')";
cmd.ExecuteNonQuery();
}
connection.Close();
}
I'm using this first code to encode three bitmap images into a base64 string, then I'm storing them in a SQLite database.
public Form1()
{
InitializeComponent();
RefreshData();
using SQLiteConnection PicCheckerConnection = new(DBpath);
using var cmd = new SQLiteCommand(DBpath, PicCheckerConnection);
PicCheckerConnection.Open();
for (int i = 0; i <= 4; i++)
{
cmd.CommandText = "SELECT * FROM (PictureBoxes) Limit "+ i +"," + i;
cmd.ExecuteNonQuery();
using (SQLiteDataReader read = cmd.ExecuteReader())
{
while (read.Read())
{
string Base64Image = read.GetString(0);
byte[] bytes = Convert.FromBase64String(Base64Image);
Stream stream = new MemoryStream(bytes);
if (i == 1) { pictureBox1.Image = Image.FromStream(stream);}
if (i == 2) { pictureBox2.Image = Image.FromStream(stream);}
if (i == 3) { pictureBox3.Image = Image.FromStream(stream);}
}
read.Close();
}
}
Then I wrote this code where it selects all three base64 strings from the SQLite database, decodes them and puts them in their pictureboxes respectively, the first base64 string --> the first picture box, second base64 string --> second picture box, and third base64 string --> third picture box.
However, when the program decodes the base64 strings and applies the images to the pictureboxes, the order is messed up.
The second decoded image is set in the first picturebox, and the third decoded image is set in the second picturebox and the first decoded image is not set in any of the pictureboxes.
I have tried debugging and changing the value of i, but sadly they did not help.
Add a column for sorting with images to the table to store them, and sort them with the order by clause.
So I have a couple tabs in a tabcontrol which do the task of registering and modifying info about a client. The first one among other info, saves a picture using OpenFileDialog and then store it into 'lblImagePath.Text' to use bitmap with it so I can save it into de DB, which can be seen in this code:
public partial class form : Form
{
String strDBFilePath = "";
String strFilePath = "";
Image DefaultImage;
byte[] ImageByteArray;
byte[] ImageByteArrayMod;
private void btnAddUser_Click(object sender, EventArgs e)
{
if (txtEmailPersonal.Text != "")
{
try
{
Image temp = new Bitmap(strFilePath);
MemoryStream ms = new MemoryStream();
temp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
ImageByteArray = ms.ToArray();
SqlConnection con = new SqlConnection();
con.ConnectionString = CONEXION.CONEXIONMAESTRA.conexion;
con.Open();
SqlCommand cmd = new SqlCommand();
cmd = new SqlCommand("insert_user", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#email", txtEmailPersonal.Text);
cmd.Parameters.AddWithValue("#password", txtPasswordPersonal.Text);
cmd.Parameters.AddWithValue("#profile_picture", ImageByteArray);
cmd.Parameters.AddWithValue("#imageFile_name", lblImagePath.Text);
cmd.ExecuteNonQuery();
con.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
mostrar();
}
}
}
Everything goes smooth, register form works and I'm using a datagridview to visualize it. When I double click a row from the dgv, all the info loads into the second tab and let's me modify all the info except the profile picture, which can be previewed in a picturebox but doesnt load any other information about it, so when I hit the 'save changes' button, it won't let me proceed with it until I re-upload a profile picture, since path is non existant prior to that action. This is the code for user modifying:
private void btnGuardarCambiosPersonal_Click(object sender, EventArgs e)
{
if (txtEmailPersonalMod.Text != "")
{
try
{
Image temp = new Bitmap(strDBFilePath);
MemoryStream ms = new MemoryStream();
temp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
ImageByteArrayMod = ms.ToArray();
SqlConnection con = new SqlConnection();
con.ConnectionString = CONEXION.CONEXIONMAESTRA.conexion;
con.Open();
SqlCommand cmd = new SqlCommand();
cmd = new SqlCommand("modify_user", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#correo", txtEmailPersonalMod.Text);
cmd.Parameters.AddWithValue("#password", txtPasswordPersonalMod.Text);
cmd.Parameters.AddWithValue("#profile_picture", ImageByteArrayMod);
cmd.Parameters.AddWithValue("#imageFile_name", lblFilePathMod.Text);
cmd.ExecuteNonQuery();
con.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
mostrar();
}
}
Some of the stuff I have in there might actually be useless to accomplish what I want. So I'll try to be as clear as possible, I want to be able to keep the current profile picture if another profile picture isn't uploaded to replace it.
As you might also see, instead of doing the query directly on the code, I'm using stored procedures, the idea is to keep those stored procedures and try to do the adjusting in the code.
After reading #Llama 's comments, I realized solution was very simple, over the modifying code, I added this at the beginning of the try/catch:
Image tempy = new Bitmap(picPerfilMod.Image);
MemoryStream mems = new MemoryStream();
tempy.Save(mems, System.Drawing.Imaging.ImageFormat.Jpeg);
ImageByteArrayMod = mems.ToArray();
so I could turn image from picturebox back to array and without the need to modify it.
I will keep reading about varbinary column type use for this cases, since it clearly looks like a better/simpler idea.
I have a form where a user can capture information about an invoice. As part of that form the user can upload and save a pdf file copy of that invoice into the database.
I am using the same form to save a new invoice and to edit already captured invoices.
The problem I have is that when a user edits an already existing invoice and saves their changes, the pdf file invoice is overwritten with a blank.
I am not sure how to solve this problem and retrieve the already saved pdf file invoice so that when the user saves their changes the pdf file invoice doesn't get overwritten with a blank.
This is what I have so far:
public void PopulateForm()
{
SqlConnection con = new SqlConnection(
WebConfigurationManager.ConnectionStrings["MyDbConn"].ConnectionString);
con.Open();
SqlDataReader myReader = null;
SqlCommand cmd = new SqlCommand("sp_displayVsoftInvoice", con);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("VSoftInvoiceID", txtID.Text);
myReader = cmd.ExecuteReader();
while (myReader.Read())
{
txtInvoiceNo.Text = (myReader["InvoiceNo"].ToString());
ddlInvoiceType.SelectedValue = (myReader["EventTypeID"].ToString());
txtDateSent.Text = (myReader["DateSent"].ToString());
txtDatePaid.Text = (myReader["DatePaid"].ToString());
string InvSent = (myReader["InvoiceSent"].ToString());
string InvPaid = (myReader["InvoicePaid"].ToString());
if (InvSent == "True")
{
cbxInvSent.Checked = true;
}
if (InvPaid == "True")
{
cbxInvPaid.Checked = true;
}
}
con.Close();
}
protected void btnSaveInvoice_Click(object sender, EventArgs e)
{
string filename = Path.GetFileName(FileUpload1.PostedFile.FileName);
string contentType = FileUpload1.PostedFile.ContentType;
using (Stream fs = FileUpload1.PostedFile.InputStream)
{
using (BinaryReader br = new BinaryReader(fs))
{
byte[] bytes = br.ReadBytes((Int32)fs.Length);
SqlConnection con = new SqlConnection(
WebConfigurationManager.ConnectionStrings["MyDbConn"].ConnectionString);
con.Open();
SqlCommand cmd = new SqlCommand("sp_insertUpdateVsoftInvoice", con);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("VSoftInvoiceID", txtID.Text);
cmd.Parameters.AddWithValue("CenterID", ddlCenter.SelectedItem.Value);
cmd.Parameters.AddWithValue("InvoiceTypeID", ddlInvoiceType.SelectedItem.Value);
cmd.Parameters.AddWithValue("InvoiceNo", txtInvoiceNo.Text);
cmd.Parameters.AddWithValue("InvoiceSent", this.cbxInvSent.Checked ? "1" : "0");
cmd.Parameters.AddWithValue("InvoicePaid", this.cbxInvPaid.Checked ? "1" : "0");
cmd.Parameters.AddWithValue("DateSent", txtDateSent.Text);
cmd.Parameters.AddWithValue("DatePaid", txtDatePaid.Text);
cmd.Parameters.AddWithValue("InvoiceName", filename);
cmd.Parameters.AddWithValue("ContentType", contentType);
cmd.Parameters.AddWithValue("Data", bytes);
cmd.Parameters.AddWithValue("ModifiedBy", txtUser.Text);
cmd.Parameters.AddWithValue("DateModified", DateTime.Now);
cmd.ExecuteNonQuery();
con.Close();
Response.Redirect("VsoftInvoice.aspx");
}
}
}
Please advise me on how I can solve this problem so that my already saved pdf invoice doesn't get overwritten with a blank.
Thanks in advance!
We need to clarify one of two things:
1- is that happening when editing without uploading a document?if yes then I think you need to save the file only when there is file uploaded (modifying your btnSaveInvoice_Click method)
2- if there is another edit method then please share the code
Good luck further.
i have created simple project in c# to save file data into Oracle Database using BLOB data type and it worked. i used devexpress gridcontrol to show the data. This is the sample data that i have created.
in the btnDownload will download data from blob oracle that i selected row. here is my code:
var rowHandle = gridView1.FocusedRowHandle;
var obj = gridView1.GetRowCellValue(rowHandle, "FILENAME");
if(koneksidb.con.State == ConnectionState.Open)
{
koneksidb.con.Close();
}
koneksidb.con.Open();
OracleCommand cmd = new OracleCommand();
OracleDataReader dr;
cmd.CommandText = #"SELECT * FROM LATIHANFILEMANAGER WHERE FILENAME='"+ obj +"'";
cmd.Connection = koneksidb.con;
dr = cmd.ExecuteReader();
while(dr.Read())
{
UInt32 FileSize = Convert.ToUInt32(dr.GetInt32(dr.GetOrdinal("FILESIZE"))); //get file size from table LATIHANFILEMANAGER
rawData = new byte[FileSize];
var nilai = dr.GetBytes(dr.GetOrdinal("FILEDATA"), 0, rawData, 0, (int)FileSize); //this file that i wanna download
FileStream fls = new FileStream(#"D:\newfile.png", FileMode.OpenOrCreate, FileAccess.Write);
fls.Write(rawData, 0, (int)FileSize);
fls.Close();
}
dr.Close();
when i run this project and download the image, i got a file and file size but it cannot be opened.
here is the file that i captured:
this tutorial i got from this link:
https://docs.oracle.com/cd/E17952_01/connector-net-en/connector-net-programming-blob-reading.html
any suggest?
first, you show your Image(BLOB) from database to PictureBox, than use SaveFileDialog.
for more information visit
How to use saveFileDialog for saving images in C#?
I am creating a web form application that allows a user to upload image file to a folder and store its path in a database. There is a data-list that is populated by the image path. I want the functionality to download image when it is selected from data-list. I am new to it and didn't get clear guidance from other questions.
Kindly help me.
Here is my code for uploading file
try
{
if (FileUploadzz.HasFile)
{
Guid g = Guid.NewGuid();
string strguid = g.ToString();
string uniqueString = strguid + FileUploadzz.FileName;
FileUploadzz.SaveAs(Server.MapPath(#"~\AllUploads\AllUserImages\" + uniqueString));
DataClasses1DataContext db2 = new DataClasses1DataContext();
Picture p = new Picture();
p.picturePath = "http://localhost:12237/AllUploads//AllUserImages/" + uniqueString;
db2.Pictures.InsertOnSubmit(p);
db2.SubmitChanges();
}
}
catch (Exception)
{
throw;
}
I have a button in my datalist itemtemplate that I want to use for downloading that specific image I need help on downloading the image when button is clicked. I have image control and a button (button1) in item template of datalist. I have already populated my datalist succesfully with images. please let me know how to download that image on OnCLlick event of that button1.
This code works in a way like you've to pass and image id to the function and w.r.t. that you can fetch specific image. This code will act like a base. If you want to fetch all the images at same time then still you can do using while loop. You can do deserializing one by one. So according to your purpose small changes need to be done.
private System.Windows.Forms.PictureBox picImage;
SqlConnection con = new SqlConnection(GetConnectionString());
SqlCommand cmd = new SqlCommand("ReadImage", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#imgId", SqlDbType.Int).Value = Convert.ToInt32(cmbImageID.SelectedValue.ToString());
SqlDataAdapter adp = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
try
{
if (con.State == ConnectionState.Closed)
con.Open();
adp.Fill(dt);
if (dt.Rows.Count > 0)
{
MemoryStream ms = new MemoryStream((byte[])dt.Rows[0]["ImageData"]);
picImage.Image = Image.FromStream(ms);
picImage.Image.Save(#"Complete path of location", ImageFormat.Jpeg);
}
}
catch (Exception ex)//catch if any error occur
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
if (con.State == ConnectionState.Open)//check whether connection to database is open or not
con.Close();
}
}