getting error while trying to change image source wpf C# - c#

I have a DataGrid in my wpf window, and it's got a ContextMenu with items Update and Delete
When Update is Clicked the selected item's Name, UserName etc... is shown in TextBoxes of the window, so that the user can change them (when the user clicks on a addUserBtn the changes are saved to database)
Now,
one of the User's properties is thier Image, and i show that image using Image element in WPF. the source of the image is by default a file inside the project. but when Update is clicked, the ImageSource becomes the User's Image's address (gotten from database)
I've used the code below to Copy the image file into the application's executable path, and then save the file's address in the database
string SavePic(string UserName)
{
string path = System.IO.Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName) + #"\UserPictures\";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string picName = UserName + ".jpg";
try
{
string picPath = ofd.FileName;
File.Copy(picPath, path + picName, true);
}
catch (Exception e)
{
MyMessageBox mb = new MyMessageBox("System was unable to save the picture\n" + e.Message);
mb.ShowDialog();
}
return path + picName;
}
So far so good
But the problem is when i try to save the changes (after clicking on UpdateContextMenu).
Weather I change the image or not, i get an error
Let's say I only want to change the User's Name, but the image is untouched, then I get this error .Empty file name is not legal Parameter name: sourceFileName
And if I change the image, I get this other error => The process cannot access the file 'C:Usersetc....because it is being used by another process
Just in case, this is the code, behind UpdateContextMenu button:
flagUpdate = true;
User temp = bll.Read(idValue);
txtName.Text = temp.Name;
txtUsername.Text = temp.UserName;
if (temp.Picture != null)
{
ProfilePicImage.Source = new BitmapImage(new Uri(temp.Picture));
}
else
{
ProfilePicImage.Source = new BitmapImage(new Uri("pack://application:,,,/Image/UserWindow/UserProfileImage.png"));
}
And this is the code behind addUserBtn which saves the new values to the database:
User tempId = bll.Read(idValue);
User temp = new User();
temp.Name = txtName.Text;
temp.UserName = txtUsername.Text;
temp.Picture = SavePic(txtUsername.Text);
if (txtPassword.Text != "")
{
temp.Password = txtPassword.Text;
}
string action = bll.Update(temp, idValue);
ProfilePicImage.Source = new BitmapImage(new Uri("pack://application:,,,/Image/UserWindow/UserProfileImage.png"));
flagUpdate = false;
MyMessageBox mb = new MyMessageBox(action);
OpenWindow(mb);
DataGridFill();
it got very long :)
just wanted to give you all the information just in case, since I myself am clueless about what I should do

Related

Trying to use File Upload in Listview? Update not working

Here is my ListView. I'm using the OnItemCommand to reference the code in code-behind. Here I'm trying to Update the database with the new FileUpload control.
<%--Listview--%>
<asp:ListView runat="server" ID="livLocation" class="container"
DataKeyNames="LocationID"
DataSourceID="sdsListViewLocation"
EmptyDataText="No data to display"
InsertItemPosition="FirstItem"
OnItemInserted="livLocation_ItemInserted"
OnItemUpdated="livLocation_ItemUpdated"
OnItemDeleted="livLocation_ItemDeleted"
OnItemCanceling="livLocation_ItemCanceling"
OnItemCommand="livLocation_ItemCommand">
</asp:ListView>
The Insert works perfectly fine. When an Update is executed a Null error is thrown for all FindControls. I believe for some reason the FindControls are not working for the Update. I have tried giving each control their own id's but that still didn't fix the problem. I have been referencing this post but nothing has helped so far: Upload images with fileupload within a Listview asp.net
protected void livLocation_ItemCommand(object sender, ListViewCommandEventArgs e)
{
//
if (e.CommandName == "Insert")
{
// Find controls on insert.
TextBox txtLocation = (TextBox)livLocation.InsertItem.FindControl("txtLocation");
TextBox txtImage = (TextBox)livLocation.InsertItem.FindControl("txtImage");
FileUpload fuiImage = (FileUpload)livLocation.InsertItem.FindControl("fuiImage");
// Get today's date
String strDate = DateTime.Now.ToString("MM-dd-yyyy-h-m-stt");
// If file is there to upload.
if (fuiImage.HasFile)
{
// Set path.
String strFileName = txtLocation.Text + "-" + strDate + ".jpg";
String strPath = Request.PhysicalApplicationPath + "Image\\Location\\" + strFileName;
// Save file.
fuiImage.SaveAs(strPath);
// Fill Image textbox
txtImage.Text = strFileName;
}
else
{
// Do nothing
}
}
else if (e.CommandName == "Update")
{
// Find controls on insert.
TextBox txtLocation = (TextBox)livLocation.InsertItem.FindControl("txtLocation");
TextBox txtImage = (TextBox)livLocation.InsertItem.FindControl("txtImage");
FileUpload fuiImage = (FileUpload)livLocation.InsertItem.FindControl("fuiImage");
// Get today's date
String strDate = DateTime.Now.ToString("MM-dd-yyyy-h-m-stt");
// If file is there to upload.
if (fuiImage.HasFile)
{
// Set path.
String strFileName = txtLocation.Text + "-" + strDate + ".jpg";
String strPath = Request.PhysicalApplicationPath + "Image\\Location\\" + strFileName;
// Save file.
fuiImage.SaveAs(strPath);
// Fill Image textbox
txtImage.Text = strFileName;
}
else
{
// Do nothing
}
}
else if (e.CommandName == "Delete")
{
// Delete file.
FileUpload fuiImage = (FileUpload)livLocation.InsertItem.FindControl("fuiImage");
String strPath = Request.PhysicalApplicationPath + "Image\\Location\\" + fuiImage.FileName;
System.IO.File.Delete("strPath");
}
else
{
// Do nothing
}
}
}
As discussed its always nice to use the sender object for better maintainability later. for your issue kindly visit the following link to get the edited item as your syntax is not correct: https://learn.microsoft.com/en-us/dotnet/api/system.web.ui.webcontrols.listview.itemediting?view=netframework-4.8
it shows more details about item editing and how to fetch the edited item with the new edit index.
the
(TextBox)livLocation.InsertItem is incorrect it must be EditItem
so it will be (FileUpload)(sender as ListView).EditItem.FindControl.....

Adding a picture to a checkbox list after binding

Is there any way to populate a checkbox list through datasource/ databind and then actually add an image to each checkbox? i know how to do both separately but cant seem to figure out how to make them work together.
Essentially i will have a checkbox list of students for teachers to select from and i've been asked to put a picture of each student next to the checkbox.
The way i get images currently is i have a webform which intakes an ID in the url and then it grabs the blob off the database then converts the binary into a thumbnail image, saves that locally then redirects to it. then when i want to get an image on a different webform i just need to use Response.Redirect("imgs.aspx?ID=[Student Id]") and it will put in a small image of the student, is there any way to modify a checkbox list so that i can call on the imgs webform and display the image of the student next to their checkbox?
Code behind imgs.aspx:
protected void Page_Load(object sender, EventArgs e)
{
var stuId = Request.QueryString["ID"];
if (stuId.Length <= 0)
{
stuId = "100097645"; // If no ID number sent, display default 'image not available' thumbnail.
}
var con = new SqlConnection
{
ConnectionString =
removed for security reasons
};
con.Open();
var sqlCommand = new SqlCommand("Select BINARY_OBJECT FROM BLOBS WHERE OWNER_REF=" + stuId, con);
var reader = sqlCommand.ExecuteReader(CommandBehavior.CloseConnection);
reader.Read();
var byteArray = (byte[])reader["BINARY_OBJECT"];
var mstream = new System.IO.MemoryStream(byteArray, 0, byteArray.Length);
var dbImage = System.Drawing.Image.FromStream(new System.IO.MemoryStream(byteArray));
var thumbnailImage = dbImage.GetThumbnailImage(100, 100, null, new IntPtr());
thumbnailImage.Save(mstream, dbImage.RawFormat);
var thumbnailByteArray = new byte[mstream.Length];
mstream.Position = 0;
mstream.Read(thumbnailByteArray, 0, Convert.ToInt32(mstream.Length));
Response.Clear();
Response.BinaryWrite(thumbnailByteArray);
}
code i have so far to display the image:
private void StudentSelected()
{
string query = "Select distinct (Convert(varchar, PERSON_CODE) + '|' + FORENAME + ' ' + SURNAME) as StudentName, (Convert(varchar, PERSON_CODE) + '|' + FORENAME + '|' + SURNAME) as StudentValue From people where (FORENAME = '" + stuforename + "') and (SURNAME = '" + stusurname + "') and (Convert(varchar,PERSON_CODE) = '" + stuid + "')";
StudentCheckBoxData.Merge(GetData(query));
cbSelection.DataSource = StudentCheckBoxData;
cbSelection.DataTextField = "StudentName";
cbSelection.DataValueField = "StudentValue";
cbSelection.DataBind();
try
{
foreach (ListItem checkBox in cbSelection.Items)
{
checkBox.Text += string.Format("<img src = \"{0}\" /> ", GetImageUrl(checkBox.Text.Split('|')[0]));
}
}
catch
{
//Display Error Here
}
}
private string GetImageUrl(string id)
{
return string.Format("http://bceforms/Contact/imgs.aspx?ID=", id);
}
The problem at the moment is it shows the border but the image that appears is a Thumbnail not found image, when i've had this issue before it's been because image hasn't been databound however when i then use .databind(); on the checkbox List because it obviously the original datasource doesn't have the image, it just removes the image
Any help would be apprecieated
I do not think it is a good way in performance to save image data in sql, Instead you can save the image url in the sql and save the image file. And at the end of your code you have a problem:
private string GetImageUrl(string id)
{
return string.Format("http://bceforms/Contact/imgs.aspx?ID=", id);
}
You must change that to this:
private string GetImageUrl(string id)
{
return string.Format("http://bceforms/Contact/imgs.aspx?ID={0}", id);
}
After fixing this, Please let know the result.

Using the UPDATE MySQL Command in C#

Suppose I have this method from one class:
private void btnChangeImage_Click(object sender, EventArgs e)
{
using (var openFileDialogForImgUser = new OpenFileDialog())
{
string location = null;
string fileName = null;
openFileDialogForImgUser.Filter = "Image Files (*.jpg, *.png, *.gif, *.bmp)|*.jpg; *.png; *.gif; *.bmp|All Files (*.*)|*.*"; // filtering only picture file types
var openFileResult = openFileDialogForImgUser.ShowDialog(); // show the file open dialog box
if (openFileResult == DialogResult.OK)
{
using (var formSaveImg = new FormSave())
{
var saveResult = formSaveImg.ShowDialog();
if (saveResult == DialogResult.Yes)
{
imgUser.Image = new Bitmap(openFileDialogForImgUser.FileName); //showing the image opened in the picturebox
location = openFileDialogForImgUser.FileName;
fileName = openFileDialogForImgUser.SafeFileName;
FileStream fs = new FileStream(location, FileMode.Open, FileAccess.Read); //Creating a filestream to open the image file
int fileLength = (int)fs.Length; // getting the length of the file in bytes
byte[] rawdata = new byte[fileLength]; // creating an array to store the image as bytes
fs.Read(rawdata, 0, (int)fileLength); // using the filestream and converting the image to bits and storing it in an array
MySQLOperations MySQLOperationsObj = new MySQLOperations("localhost", "root", "myPass");
MySQLOperationsObj.saveImage(rawdata);
fs.Close();
}
else
openFileDialogForImgUser.Dispose();
}
}
}
}
And this method from another class (MySQLOperations):
public void saveImage(byte[] rawdata)
{
try
{
string myConnectionString = "Data Source = " + server + "; User = " + user + "; Port = 3306; Password = " + password + ";";
MySqlConnection myConnection = new MySqlConnection(myConnectionString);
string currentUser = FormLogin.userID;
string useDataBaseCommand = "USE " + dbName + ";";
string updateTableCommand = "UPDATE tblUsers SET UserImage = #file WHERE Username = \'" + currentUser + "\';";
MySqlCommand myCommand = new MySqlCommand(useDataBaseCommand + updateTableCommand, myConnection);
myCommand.Parameters.AddWithValue("#file", rawdata);
myConnection.Open();
myCommand.ExecuteNonQuery();
myConnection.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
If I must, this is my constructor for the MySQLOperations class:
public MySQLOperations(string server, string user, string password)
{
this.server = server;
this.user = user;
this.password = password;
}
What I'm trying to do is save an image file (which the user selects through the open file dialog box) to the database. Problem is I get this error: "You have an error in your SQL syntax; check the manual that correponds to your MySQL server version for the right syntax to use near ';UPDATE tblUsers SET UserImage = _binary'?PNG ... (and so on with some random characters). So, I can't really save the file in the database. I would love to post a picture on how the error is seen at the MessageBox, but I guess my account is not given the privilege to do so yet.
I'm not really sure where the syntax error is in that. I'm thinking, it's in the #file - but that's just a guess. Your help would be very much appreciated.
And oh, the table column UserImage has a type of LONGBLOB.
Other things I'm interested to know about also:
Is it necessary that I add another column for my table to store the
size of the file (because I'm going to need to retrieve the file
to display the image later on)?
Is it okay that I used the using statement that way in the method
btnChangeImage_Click?
Thank you very much.
EDIT: Got the problem solved. Such a simple thing not given attention to. Thanks to everybody who tried to help. I'm still willing to hear your opinion on the questions at the bottom (those on bullets).
I think the problem is in the following line of code:
WHERE Username = \'" + currentUser + "\';"
It should change to the following one:
WHERE Username = " + currentUser;
Or better (to avoid sql injections) to the following one:
WHERE Username = #Username";
myCommand.Parameters.AddWithValue("#Username", currentUser);
Do not store binary files in a MySQL table. Instead, save it to disk and save path to PNG file to MySQL database. Also, use Christos advice to avoid SQL injections.

how upload image to folder and display it

I try to upload image to folder (using FileUpload) by pressing one submit button to whole form. i manage to upload the image to separate folders but i can't display it.
thank you.
String fname;
FileUpload tempFU = new FileUpload();
string path = Server.MapPath(".") + "\\images\\" + ulProj.groupCode;
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
try
{
tempFU = (FileUpload)customerUC.FindControl("CustomerLogoUrlFU");
Directory.CreateDirectory(path);
fname = path + "\\" + tempFU.FileName;
tempFU.SaveAs(fname);
tempCus.logoUrl = fname;
}
catch
{
//return;
}
Points to remember:
you should use tilde ~ operator to represent the current project
root folder.
use System.IO.Path.Combine() to combine your path and filename to get the valid complete path.
you are creating the Directory for the given path 2 times. so remove the later part where you are creating the Directory 2'nd time.
as said in the above comments as your catch block is not having anycode,
remove the try-catch block
Complete Solution:
String fname;
FileUpload tempFU = new FileUpload();
string path = Server.MapPath(#"~\images\" + ulProj.groupCode);
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
tempFU = (FileUpload)customerUC.FindControl("CustomerLogoUrlFU");
fname = System.IO.Path.Combine(path,tempFU.FileName);
tempFU.SaveAs(fname);
tempCus.logoUrl = fname;

Load picture from SQL database asp.net C#

I have avatars stored in a database. I have used the the data type image for the avatars. I want to load the avatar of a user into an image control, but i cant get it to work. I have tried this code without any luck:
public void GetUserAvatar()
{
string username = Convert.ToString(Session["username"]);
var image = from u in dc.Users
where u.username == username
select u.image;
imgAvatar.Controls.Add(image);
}
I think i might have to save the images to a folder and then save the file path in the database instead. This seems to be easier and smoother. Any ideas?
I ended up saving the image to a folder and then saving the path to the database. My code for image uploading now looks like this:
public void addImage()
{
if (fuAvatar.PostedFile.ContentType.ToLower().StartsWith
("image") && fuAvatar.HasFile)
{
string saveLocation = Server.MapPath("savedAvatars/");
string fileExtension = System.IO.Path.GetExtension(fuAvatar.FileName);
string fileName = Convert.ToString(Session["userid"]);
string savePath = saveLocation + fileName + fileExtension;
fuAvatar.SaveAs(savePath);
string imageDBPath = fileName + fileExtension;
LinqClass1DataContext dc = new LinqClass1DataContext();
int userid = Convert.ToInt32(Session["userid"]);
var tblUser = (from u in dc.Users
where u.userid == userid
select u).First();
tblUser.imagePath = #"\savedAvatars\"+imageDBPath;
dc.SubmitChanges();
lblResult.Text = "Avatar lastet opp!";
}
else lblResult.Text = "Avatar ikke lastet opp!";
}
And to load the picture:
public void GetUserAvatar()
{
int userid = Convert.ToInt32(Session["userid"]);
var varPath = dc.Users.Single(u => (u.userid == userid)).imagePath;
string imagePath = Convert.ToString(varPath);
imgAvatar.ImageUrl = imagePath;
}
you should add a generic handler file (.ashx) and write in it something like that:
string sql = "select image from table1";
SqlCommand command = new SqlCommand(sql, con);
SqlDataReader dReader = command.ExecuteReader();
dReader.Read();
context.Response.BinaryWrite((byte[])dReader["Source"]);
dReader.Close();
then in your page do something like this:
img.ImageUrl = "Handler.ashx;
http://www.dotnetcurry.com/ShowArticle.aspx?ID=129 read this article, first I've found. Basically you need to create a handler which responds with the raw image.
Please find the answer in below link.
Get images from database using Handler
You will have to create a handler which will load the image and u can pass the source to image
tag.

Categories