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.
Related
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 a SQL Server Database. I have stored an image in there which is a varbinary(max). I inserted the image the following way :
string consString = ConfigurationManager.ConnectionStrings["connection"].ConnectionString;
SqlConnection con = new SqlConnection(consString);
con.Open();
String filePath = fuImage.PostedFile.FileName;
String naam = Path.GetFileName(filePath);
String extension = Path.GetExtension(naam);
Stream stream = fuImage.PostedFile.InputStream;
BinaryReader br = new BinaryReader(stream);
Byte[] imgByte = br.ReadBytes((Int32)stream.Length);
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "spAddImage";
cmd.Parameters.AddWithValue("#FOTO", imgByte);
cmd.Parameters.AddWithValue("#ARTIEST", ddlArtiest.SelectedValue);
cmd.Connection = con;
cmd.ExecuteNonQuery();
con.Close();
The image now looks like this in the database :
It is stored as a varbinary.
http://puu.sh/ikF83/6a03b52520.png <--- database
Now I want to display my image on my asp.net page that I have inserted.
But I have no idea how I can achieve this.
You could use SqlDataReader to go over the results and get back what you need
var reader = cmd.ExecuteReader();
while (reader.Read())
{
byte[] myImage = (byte[])reader["MyImageColumn"];
}
This is from top of my head so make your adjustments as required. But it should give you the basic idea.
Furthermore, It's strongly recommended to use the using block as it ensures the object is disposed correctly.
So you could change your code to
using(var connection = new SqlConnection(connectionString))
{
//Your command
connection.Open();
//Datareader here
}//Object disposed here
Reference to SqlDataReader
Reference to using block
Extending the answer provided by Izzy, below is how we have implemented the same.
public HttpResponseMessage RenderImage(RenderRequest renderRequest, HttpRequestMessage request)
{
var httpResponse = new HttpResponseMessage();
try
{
var reader = cmd.ExecuteReader();
while (reader.Read())
{
byte[] imagebytes = (byte[])reader["MyImageColumn"];
}
return httpResponse = request.CreateResponse<byte[]>(HttpStatusCode.OK, imagebytes, new ImageMediaFormatter("image/png"));
}
catch ()
{
throw;
}
}
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();
}
}
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
I m using a handler to display images on my page from database
public void ProcessRequest (HttpContext context)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = ConfigurationManager.ConnectionStrings["XYZ"].ConnectionString;
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "Select Image from EmployeeInfo where Emp_Id = #ID";
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
SqlParameter ImageID = new SqlParameter("#ID", System.Data.SqlDbType.Int);
ImageID.Value = context.Request.QueryString["ID"];
int height = Convert.ToInt32(context.Request.QueryString["Ht"]);
int width = Convert.ToInt32(context.Request.QueryString["Wt"]);
cmd.Parameters.Add(ImageID);
con.Open();
SqlDataReader dReader = cmd.ExecuteReader();
if (dReader.HasRows)
{
dReader.Read();
byte[] imagethumbnail = null;
try
{
imagethumbnail = MakeThumbnail((byte[])dReader["Image"], width, height);
}
catch
{
}
context.Response.BinaryWrite(imagethumbnail);
}
dReader.Close();
con.Close();
}
public static byte[] MakeThumbnail(byte[] myImage, int thumbWidth, int thumbHeight)
{
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
using (Image thumbnail = Image.FromStream(new MemoryStream(myImage)).GetThumbnailImage(thumbWidth, thumbHeight, null, new IntPtr()))
{
thumbnail.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
return ms.ToArray();
}
}
This code works fine when displaying images from database.
Now What I want to do is to Show image preview using a different Handler.
Now if u look at the above code then you can see we have image data in byte[] form.
I m uploading a image and I m able to get the data in byte[] but this data of mine is on .cs page.
context.Response.BinaryWrite(imagethumbnail);
If I use this command converting data into bytes from page, it shows me the image on page nothing else.
Can you give me any idea how to show this data into image?
There is nothing much change in the datastream
This is what I want to use but how to get byte[] from .cs page to handler.
imagethumbnail = MakeThumbnail((byte[])dReader["Image"], width, height);
context.Response.BinaryWrite(imagethumbnail);
You can seperate your database image logic into a Generic Handler (ASHX) and then use the handler as your image's src e.g.
<img src="GetImage.ashx?id=1"/>
You'd need to create GetImage.ashx and handle your id's (or whatever your using) appropriately. Then you can do a simple write back to the page.
This will allow you to dynamically pull an image from the database while using it as a seperate element on your page.