I have a product page. I want to add my product to my database and I want also to update my product.
I have a problem with images.
When I insert the product everithing is ok.. In my aspx page I have this code:
<span>
<asp:FileUpload ID="files" runat="server" AllowMultiple="true" />
</span>
<div runat="server" id="previewImages"></div>
and when I save my product, in code behind I have this code:
string filenm = string.Empty;
HttpFileCollection fileCollection = Request.Files;
for (int i = 0; i < fileCollection.Count; i++)
{
HttpPostedFile uploadfile = fileCollection[i];
if (uploadfile.ContentLength > 0)
{
string filename = uploadfile.FileName;
System.IO.Directory.CreateDirectory(Server.MapPath("immScarpe/" + txtStyle.Text));
file.SaveAs(Server.MapPath("immScarpe/" + txtStyle.Text + "/") + fileName);
//this is pseudo-code
INSERT INTO PRODUCT_IMM (IdProduct, Path) VALUES (Id, "immScarpe/" + txtStyle.Text + "/" + fileName)
}
}
Now, the problem is that I can EDIT the saved product. When I click the edit button for a product, I have to load all it's data and let the user modify them. Also the images.
the main question is: How can I load the saved images in asp:FileUpload control?
Another thing I would like to do is to show images previews...in insert and in edit.
An Example of what I want to do is the thing that amazon does
but, if it's possible with only one FileUpload with AllowMultiple = true
I am willing to use other technologies like javascript, jquery and Ajax if it's necessary
Show Images Preview - Insert
<script src="jquery-1.10.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
function ShowpImagePreview(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#previewImage').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
</script>
<asp:Image ID="previewImage" runat="server" />
<asp:FileUpload ID="FileUpload1" runat="server" onchange="ShowpImagePreview(this);" />
Here is a very basic example as to how you can handle images after they have been send to the server. In this snippet the filename of the image is fixed, but it should be enough to give you push in the right direction.
protected void Page_Load(object sender, EventArgs e)
{
//check if the file exists and show
if (File.Exists(Server.MapPath("testImage.jpg")))
{
setImage("/testImage.jpg");
}
}
//upload a new image
protected void Button1_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
try
{
FileUpload1.SaveAs(Server.MapPath("testImage.jpg"));
setImage("/testImage.jpg");
}
catch
{
//error writing file
}
}
}
//delete the image
protected void LinkButton1_Click(object sender, EventArgs e)
{
try
{
File.Delete(Server.MapPath("testImage.jpg"));
LinkButton1.Visible = false;
Image1.Visible = false;
}
catch
{
//error deleteing file
}
}
//set the image and show the delete link
private void setImage(string image)
{
Image1.ImageUrl = "/testImage.jpg";
Image1.Visible = true;
LinkButton1.Visible = true;
}
ASPX
<asp:Image ID="Image1" runat="server" Visible="false" />
<br />
<asp:LinkButton ID="LinkButton1" runat="server" Visible="false" OnClick="LinkButton1_Click">Delete image</asp:LinkButton>
<br />
<br />
<asp:FileUpload ID="FileUpload1" runat="server" />
<br />
<asp:Button ID="Button1" runat="server" Text="Upload" OnClick="Button1_Click" />
For displaying images to GridView from disk
https://www.aspsnippets.com/Articles/Display-Images-in-GridView-Control-using-the-path-stored-in-SQL-Server-database.aspx
Now you have the images shown, you want to have some replace or delete functionality on the images. You need to convert your field on the GridView for image to Template Field. You can do this by clicking on the source view of your ASPX page and replacing your ImageField or BoundField (whichever field you used in displaying the image).
See the design of the GridView on the question:
How to display image inside gridview template field without using handler class?
The way to bind the image source is in the answers in that question.
To have a delete or replace functionality, you can include a LinkButton control inside your TemplateField below the tag that displays the image.
You can set the LinkButton's CommandName property to 'Delete' or 'Replace' then on your .vb or .cs file, find the 'RowCommand' event for your GridView.
It goes something like (pseudo code only)
Protected Sub GridView_RowCommand(ByVal sender As Object, ByVal e As System.GridViewCommandEventArgs) Handles GridView.RowCommand
If e.CommandName = 'Delete' Then
'Place your delete query for your image record on the database here..
'Place your delete file from disk code here..
End If
End Sub
More info on GridView RowCommand Event
https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.rowcommand(v=vs.110).aspx
Related
I have a gridview that shows an image as part of a column. In Edit mode, I would like to let the user upload a new image file, so I'm using the FileUpload control in the edit part of the template.
When I click on update it's showing me this:
My code:
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
Label lb = GridView1.HeaderRow.FindControl("Label1") as Label;
GridViewRow row = GridView1.Rows[e.RowIndex];
FileUpload fu = row.Cells[0].FindControl("fileupload") as FileUpload;
if (fu.HasFile)
{
string file = System.IO.Path.Combine(Server.MapPath("~/uploadedimages/"), fu.FileName);
fu.SaveAs(file);
using (Ex_RepeaterEntities entities = new Ex_RepeaterEntities())
{
Student students = (from e1 in entities.Students
where e1.Id == Convert.ToInt32(lb.Text)
select e1).First();
students.Images = file;
entities.SaveChanges();
}
}
}
After a lot of searching I found solution of above error by using this code:
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
int RowID = Convert.ToInt32(GridView1.DataKeys[e.RowIndex].Value);
FileUpload fileUpload = GridView1.Rows[e.RowIndex].FindControl("fileupload") as FileUpload;
if (fileUpload.HasFile)
{
fileUpload.SaveAs(Server.MapPath("~/uploadedimages/" + fileUpload.FileName));
}
}
and at page.aspx:
<asp:TemplateField HeaderText="Upload Image" SortExpression="Names">
<EditItemTemplate>
<asp:FileUpload runat="server" ID="fileupload" />
</EditItemTemplate>
<ItemTemplate>
<asp:Image ImageUrl="~/uploadedimages/1.jpg" runat="server" ID="image" />
</ItemTemplate>
</asp:TemplateField>
But a little problem here is to solve which is that file is not saving.
Finally got my own solution of above post. Here is code to be changed:
if (fileUpload.HasFile)
{
fileUpload.SaveAs(Server.MapPath("uploadedimages/" + fileUpload.FileName));
}
I'm doing an employee registration were there is an image that the user can preview the picture they choose. So my problem is, when I tried to preview the selected image, the filename in the fileupload is gone..
the "save-14-copy.png" is the filename of the picture.
So next step is to preview the image..
So as you can see the "save-14-copy.png" is already gone after hitting the button preview.
How can I retain the filename so I will not get an error when saving it.?
Code for design:
<asp:Button runat="server" ID="Button1" Text="PREVIEW" CssClass="button-green" OnClick="Button1_Click"/>
Javascript:
<script type="text/javascript">
function ImagePreview(Imagepath) {
if (Imagepath.files && Imagepath.files[0]) {
var Filerdr = new FileReader();
Filerdr.onload = function (e) {
document.getElementById("<%= hfImage.ClientID %>").value = e.target.result;
}
Filerdr.readAsDataURL(Imagepath.files[0]);
}
}
</script>
Codebehind:
protected void Button1_Click(object sender, EventArgs e)
{
EmpImage.ImageUrl = hfImage.Value;
}
i think you should save the file at preview-click and handle the filename there
protected void Button1_Click(object sender, EventArgs e)
{
hfImagename.Value = fuFile.PostedFile.FileName;
fuFile.PostedFile.SaveAs(#"C:\foo\" +fuFile.PostedFile.FileName);
}
Your Preview button is actually causing a post back to the server. The way you have it setup now, the Preview button would be more appropriately called Upload.
You are using the FileReader object in order to read the file from the user's local file system and showing it in the image before upload. All of that should take place only in the client. Once the user is happy with the selected picture, he can upload the picture to the server.
Here is a very simple sample that should get you started.
.aspx file
<body>
<form id="form1" runat="server">
<div>
<asp:Image ID="preview" runat="server" ImageUrl="~/Images/NotSelectedYet.jpg" />
<br />
<asp:FileUpload ID="pictureOfMe" runat="server" />
<input type="button" value="Preview" onclick="Preview();" />
<br />
<asp:Button ID="Upload" runat="server" Text="Upload file to server" OnClick="Upload_Clicked" />
</div>
</form>
<script type="text/javascript">
function Preview() {
var fileInput = document.getElementById('<%= pictureOfMe.ClientID %>');
var filePreview = document.getElementById('<%= preview.ClientID %>');
var file = fileInput.files[0];
var imageType = /image.*/;
if (file.type.match(imageType)) {
var reader = new FileReader();
reader.onload = function (e) {
filePreview.src = reader.result;
}
reader.readAsDataURL(file);
}
else {
alert('Not an image file!');
}
}
</script>
</body>
Here we have an image that is showing a default picture when first loaded. Then we have a file upload control that lets the user select a picture to upload. And we have an html input button that the user clicks on to preview the selected picture. When this button is clicked, it runs javascript code that uses the FileReader to load the file an show it in the image. Note that the preview button will not cause a post back to the server.
And we also have a server button that will post the page (including the selected picture) to the server with a server event handler declared.
.aspx.cs file
public partial class TestImagePreviewAndUpload : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Upload_Clicked(object sender, EventArgs e)
{
if(pictureOfMe.PostedFile.FileName != string.Empty) {
byte[] uploadedBytes = pictureOfMe.FileBytes;
//save uploaded picture here
}
}
}
Here, in the Upload_Clicked method we check if a file was uploaded and gets the file content as a byte[]. Actuelly storing the file is left as an exercise...
Note: Sample javascript (with some modifications) from here
Recently I have been developing web form application in ASP.NET (c#):
I have an Image control:
<asp:Image ID="Avatar" runat="server" Height="225px" ImageUrl="~/Images/NoUser.jpg" Width="225px" />
And FileUpload & Button control
<asp:FileUpload ID="avatarUpload" runat="server" />
<asp:Button ID="btnUpload" runat="server" Text="Upload" OnClick="Upload" />
When user click button then "Upload" code is executed (the image is sent to the database). Problem is that I like to display the image which the user selected in Avatar Image controller before the user clicks "desperate" button.
Is that possible to do this automatically?
With the help of File Api of HTML5 (Example: Using files from web applications) you can accomplish this easily. Change the markup to use input type="file" instead of asp:FileUpload and add ID, add tag runat="server" to make it accessible from server. Your markup should look like:
<input ID="avatarUpload" type="file" name="file" onchange="previewFile()" runat="server" />
<%--<asp:FileUpload ID="avatarUpload" runat="server" />--%>
<asp:Button ID="btnUpload" runat="server" Text="Upload" OnClick="Upload" />
<asp:Image ID="Avatar" runat="server" Height="225px" ImageUrl="~/Images/NoUser.jpg" Width="225px" />
Now add a javascript function previewFile in the head of document:
<head runat="server">
<title></title>
<script type="text/javascript">
function previewFile() {
var preview = document.querySelector('#<%=Avatar.ClientID %>');
var file = document.querySelector('#<%=avatarUpload.ClientID %>').files[0];
var reader = new FileReader();
reader.onloadend = function () {
preview.src = reader.result;
}
if (file) {
reader.readAsDataURL(file);
} else {
preview.src = "";
}
}
</script>
</head>
Now after selecting an image you can see the preview like below:
You can use css to re-size it to a thumbnail.
After clicking the Upload button, in the code you can find the posted file:
protected void Upload(object sender, EventArgs e)
{
int contentLength = avatarUpload.PostedFile.ContentLength;//You may need it for validation
string contentType = avatarUpload.PostedFile.ContentType;//You may need it for validation
string fileName = avatarUpload.PostedFile.FileName;
avatarUpload.PostedFile.SaveAs(#"c:\test.tmp");//Or code to save in the DataBase.
}
I implemented the AsyncFileUpload control on a web page. This web page requires uploaded files to appear in a GridView.
The GridView contains the following columns: "File Name", "Confidential" Check Box, and a "Remove" button to remove the uploaded file.
Since the AsyncFileUpload postback does not do a full page postback, I need to "force" a postback on the OnClientUploadComplete event of the AsyncFileUpload control in order to render the gridview after uploading a file.
In the OnClientUploadCompleteEvent, I use javascript to call __doPostBack. In this postback, I only bind my GridView and display the file information (I don’t re-save the file).
The problem: On the AsyncFileUpload’s first “partial” postback, the file is successfully uploaded, as expected. On the second postback that I force with __doPostBack, the file is re-uploaded.
You can verify this by using Google Chrome, which displays the upload progress. The behaviour is as follows:
- After selecting the file, the progress increments from 0% to 100% and the file is uploaded.
- After this, the __doPostBack executes, and you can see the upload progress increment again from 0% to 100%.
How can I make sure the Gridview is properly populated, but that the file is not uploaded twice?
I attached a sample solution which contains the issue: https://www.yousendit.com/download/MzZFc2ZBNDRrYUN4dnc9PQ
There is a simpler solution
##t0x1n3Himself the solution u gave is very simple but does not work
surround the AsyncFileUpload with an update panel name it UpdatePanelAFU
then in the UpdatePanelAFU do as the following :
protected void AsyncFileUpload_UpdatePanelAFU(object sender,AjaxControlToolkit.AsyncFileUploadEventArgs e)
{
if (Request.Params.Get("__EVENTTARGET") != "UpdatePanelAFU")
return;
..... rest of the code
}
enjoy!
Maybe ugly, but works:
1)
Add a css-hidden asp:Button bellow the asp:AsyncFileUpload AsyncFileUpload1 control.
<asp:Button runat="server" ID="btnClick" Text="Update grid" style="display:none"/>
2)
On the Page_Load method, remove the if (Request.Params.Get("__EVENTTARGET") == "UploadPostback") and put its block in a simple else to the previous if.
3)
On the AsyncFileUpload1_UploadedComplete function, also remove the if (Request.Params.Get("__EVENTTARGET") != "UploadPostback") line, but leave intact everything that was inside it.
4)
Back to the aspx. Put a asp:UpdatePanel outside the grid GridView1.
<asp:UpdatePanel runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnClick" EventName="Click" />
</Triggers>
<ContentTemplate>
<asp:GridView ID="GridView1" ...
YOUR GRID CODE REMAINS THE SAME
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
5)
The last step is to change the AjaxUploadComplete client-side javascript function to make it trigger the postback.
Replace it with the following:
function AjaxUploadComplete() {
var btnClick = document.getElementById("btnClick");
btnClick.click();
}
Any file the user selects is uploaded only once.
All changes here are meant to be made in AjaxUpload.aspx & AjaxUpload.aspx.cs of your AjaxUpload.zip.
I believe #Veera had it right. UploadComplete was being called multiple times as the file was uploading. The following worked for me.
void AsyncFileUpload1_UploadedComplete(object sender, AsyncFileUploadEventArgs e) {
if (AsyncFileUpload1.IsUploading) return;
// rest of your upload code
}
I don't have access to your sample solution which contains the issue but i encounter a double postback too in my project with the AsyncFileUpload component.
I found a very simple workaround :
Just add:
private bool justUploaded = false;
Then:
void AsyncFileUpload1_UploadedComplete(object sender, AsyncFileUploadEventArgs e)
{
if (justUploaded) return;
justUploaded = true;
// rest of your upload code
}
I find this a more elegant solution, found here: http://forums.asp.net/t/1951566.aspx?AsyncFileUpload+uploads+twice) but below is my altered fully working code:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>AsyncFileUpload Example</title>
<script type = "text/javascript">
function uploadComplete(sender) {
$get("<%=lblMesg.ClientID%>").innerHTML = "File Uploaded Successfully";
clearContents();
}
function uploadError(sender) {
$get("<%=lblMesg.ClientID%>").innerHTML = "File upload failed.";
clearContents();
}
function clearContents() {
var span = $get("<%=AsyncFileUpload1.ClientID%>");
var txts = span.getElementsByTagName("input");
for (var i = 0; i < txts.length; i++) {
if (txts[i].type == "text") {
txts[i].value = "";
}
if (txts[i].type == "file") {
txts[i].value = "";
}
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<cc1:AsyncFileUpload OnClientUploadError="uploadError"
OnClientUploadComplete="uploadComplete" runat="server"
ID="AsyncFileUpload1" Width="400px" UploaderStyle="Modern" EnableViewState = "false"
UploadingBackColor="#CCFFFF" ThrobberID="imgLoader" OnUploadedComplete = "FileUploadComplete"
/>
<asp:Image ID="imgLoader" runat="server" ImageUrl = "~/images/loader.gif" />
<br />
<asp:Label ID="lblMesg" runat="server" Text=""></asp:Label>
</form>
</body>
</html>
AsyncFileUpload has a property that named IsUploading.
when this property is set to false, a postback will happen.
you can check this property like this:
if(AsyncFileUpload1.IsUploading)
{
..... upload codes
}
I used the code below for upload an image. Please let me know that why this code does not work at all. I am also using updatePanal and multiview control for tab controlling.
<asp:FileUpload ID="fuPhoto" runat="server"/>
<div style="margin-top:20px;text-align:center;">
<asp:Button ID="btnAddMemberInfo" runat="server" Text="Add" Width="100px" onclick="btnAddMemberInfo_Click" />
</div>
public byte[] GetPhtoStream()
{
byte[] bufferPhoto = new byte[fuPhoto.PostedFile.ContentLength];
Stream photoStream = fuPhoto.PostedFile.InputStream;
photoStream.Read(bufferPhoto, 0, fuPhoto.PostedFile.ContentLength);
return bufferPhoto;
}
protected void btnAddMemberInfo_Click(object sender, EventArgs e)
{
Photo = GetPhtoStream(); //Photo represent for the database field which datatype is image
}
FileUpload doesn't work in UpdatePanel with ajax postbacks. To get it work You have to register btnMemberInfo as PostBackTrigger for full postback. Then it'll work.