Click here to Skip to main content
12,400,891 members (57,495 online)
Click here to Skip to main content
Add your own
alternative version

Stats

246.8K views
5.7K downloads
71 bookmarked
Posted

Upload Images Using C#, JavaScript and ASP.NET 2.0 Client Callbacks

, 16 Jan 2007
Rate this:
Please Sign up or sign in to vote.
In this article I will demonstrate how to create a simple page that allows you to view images you wish to upload as soon as you select it from your hard drive

Introduction

There are many websites that allow you to upload images and later view them after the upload is complete. I was working on a similar website and needed the same functionality. Unfortunately, I was not intrigued by the idea of viewing the images after the upload. I wanted to view the images as soon as I select them from my hard drive. This will give me a better idea of what I am about to upload. In this article I will demonstrate how to create a simple page that allows you to view the image as soon as you select it from your hard drive.

The Idea:

Let’s first discuss how we are going to accomplish this task. First we need a page which will allow the user to select a file. Once, the user has selected the file we upload the file to the server’s folder and return the user with the url of the image that corresponds to the server’s folder. Once, we get the url we will create child image controls and add to our container. We will use the <DIV> element as our container which will contain other <DIV> elements which in turn will contain the image elements.

Uploading the Image to the Server’s Folder:

The uploading of the image is performed by ASP.NET 2.0 Client Callbacks. If you are not familiar with client callbacks then I suggest that you take a look at my article Client Callbacks in ASP.NET 2.0. The callback is fired as soon as the file is selected by the user using the file field control.

Select a file:

<input id="File1" runat="server" onchange="PopulateList(this)" name="File1"
       type="File" /> 

The PopulateList function is fired on the onchange event of the file field control.

function PopulateList(obj)
{
    // Upload the image to the server folder
    filePath =  obj.value;
    // calls the server's method using client callbacks   
    CallServer(obj.value,'');   
}

Another important point to note is that we are capturing the file path from the file field control into a public variable “filePath”. The CallServer function fires the server’s method which is responsible for uploading the file. Once, the CallServer function is fired it calls the RaiseCallbackEvent method.

public void RaiseCallbackEvent(string eventArgument)
    {
        if (!String.IsNullOrEmpty(eventArgument))
        {
            returnValue = eventArgument;
        } 
 
    }

The returnValue is a global protected variable which stores the file path that the user has selected.

The GetCallbackResult method is responsible for uploading the file to the server’s folder. The “Images” folder is the server folder where we need to upload all the selected images.

public string GetCallbackResult()
    {
        string fileName = System.IO.Path.GetFileName(returnValue);
        string path = Server.MapPath("Images/");
        string fullPath = path + fileName;
 
        Stream s = File.OpenRead(returnValue);
 
        byte[] buffer = new byte[s.Length];
        s.Read(buffer, 0, (int) s.Length);
      
        int len = (int) s.Length;
 
        s.Dispose();
        s.Close();
 
        FileStream fs = new FileStream(fullPath, FileMode.Create);
        fs.Write(buffer, 0, len);
 
        Bitmap bmp = new Bitmap(fs);
 
 
        if (System.IO.Path.GetExtension(returnValue).Equals(".gif"))
        {
            bmp.Save(fs, ImageFormat.Gif);
        }
        else
        {
            bmp.Save(fs, ImageFormat.Jpeg);
        }
 
        bmp.Dispose();
       
        fs.Dispose(); 
        fs.Close();                     
 
        return "Images/"+ fileName;
    }

The GetCallbackResult is the heart of the application. This method is responsible for reading the file into the buffer using the file path as selected by the user. Once, the file is read it is written back to the server’s folder as a jpeg or gif image. The GetCallbackResult method returns the new path to the file name to the ReceiveServerData function defined in the HTML code.

function ReceiveServerData(rValue)
{
  // The new path will contain the path of the image which is inside the
  // server's folder
  newPath = rValue; 
  CreateNestedElements();
}

The new path is stored in the global variable called “newPath”. Finally, the CreateNestedElements() function is fired which appends the new child elements to the parent DIV “FileList”.

Creating Nested Elements:

Now, let’s see how we create nested elements. The idea is to have one parent div which is the “fileList”. The fileList (div) will contain several child div elements which will contain the delete button and the image element. The CreateNestedElements function is responsible for appending the new elements to the fileList div element.

function CreateNestedElements()
 {
    var obj = document.getElementById("fileList");    
  
    var divElement = document.createElement('div');
    divElement.id = 'div' + counter;
   
    var deleteButton = document.createElement('button');
    deleteButton.value = 'Delete';
    deleteButton.innerHTML = 'Delete';
    deleteButton.onclick = DeleteItem;
   
    var imageObject = document.createElement('img');   
      
    imageObject.src = newPath;
   
    var textNode = document.createTextNode(filePath);   
  
    divElement.appendChild(textNode);
    divElement.appendChild(deleteButton);
    divElement.appendChild(imageObject);  
    
    document.getElementById("fileList").appendChild(divElement);  
   
    counter++;  
 }

Each nested div element is given assigned an ID which uniquely identifies that element. Take a look at the image below:

Sample image

Now, if you run the application you can select the image file from your hard drive and as soon as you select the image it will be displayed in the fileList element.

Sample image

Aren’t the cats too cute?

Deleting the Selected Item:

Sometimes, you are not happy with your selection and want to delete an item from the list. Let’s see how to delete the selected item. When we created the delete button we also wired its onclick event.

var deleteButton = document.createElement('button');
    deleteButton.value = 'Delete';
    deleteButton.innerHTML = 'Delete';
    deleteButton.onclick = DeleteItem;

When the delete button is pressed the DeleteItem function is fired.

function DeleteItem(e)
{
    var evt = e || window.event;
    var evtTarget = evt.target || evt.srcElement;
   
     
   // IE
    if(evtTarget.parentElement) {
    var childDiv = evtTarget.parentElement;
    childDiv.parentElement.removeChild(childDiv);
    }
   
    // FIREFOX
    else if(evtTarget.parentNode)
    {
        var childDiv = evtTarget.parentNode;
        childDiv.parentNode.removeChild(childDiv);
    }
   
}

The DeleteItem function takes the event as the parameter. First, we get the evtTarget which in our case will be the button control. Then we find its parent which will be a nested DIV. Finally, we remove the child DIV from the parent DIV. The DeleteItem function is browser compatible and will work for both IE and Mozilla.

Saving the Selected Files:

Here I am not talking about saving the selected images to the database but saving them so we can access them in the code behind. Once, we get the images in the code behind we can read them using their path and get a byte[] which can be saved in the database.

I am using a hidden field to hold all the selected paths.

<input type="hidden" id="list" runat="server" /> 

Also, note that the hidden field is marked with runat="server" attribute. This will make it possible to access the hidden field on the server side. The Save function is fired when we press the submit button.

function Save() 
{ 
    document.getElementById("list").value = ""; 
    var path = ''; 
  
    var divObject = document.getElementById("fileList"); 
   
    var divChilds = divObject.childNodes; 
   
    for(i=0; i<divChilds.length; i++) 
    { 
   
        var path = divChilds[i].innerHTML; 
        var index = path.indexOf("<BUTTON>",0); 
          
        document.getElementById("list").value += path.substring(0,index); 
        document.getElementById("list").value += "|";      
    }   
     
} 

Each image path is separated by a “|” symbol.

Accessing the Hidden Field on the Server Side:

The hidden field values are extracted in the Page_Load method.

string[] filePaths = null; 
  
        HtmlInputHidden hiddenControl = (HtmlInputHidden) 
                                               Page.FindControl("list"); 
        if (!String.IsNullOrEmpty(hiddenControl.Value)) 
        { 
            filePaths = hiddenControl.Value.Split('|'); 
  
            SaveFilesToDB(filePaths); 
           
        } 

Once, we got all the filePaths we can send it to the SaveFilesToDB method to save the files in the database.

Conclusion

It is always good to provide the user with a preview of the image they are trying to upload. This also avoids confusion when uploading the images. You can also extend this article by adding validation and support for more image types.

I hope you liked the article, happy coding!

NOTE: The code to register the Client Callbacks is in the download.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

azamsharp
Web Developer
United States United States
I am the founder of knowledge base website, HighOnCoding, GridViewGuy, RefactorCode.com and ScreencastADay.com.

HighOnCoding is a website which will get you high legally with useful information. There are tons of articles, videos and podcasts hosted on HighOnCoding.

HighOnCoding.com www.HighOnCoding.com


My Blog:

Blog



Buy my iPhone app ABC Pop

You may also be interested in...

Comments and Discussions

 
GeneralMy vote of 1 Pin
Md. Humayun Rashed13-Apr-12 2:47
memberMd. Humayun Rashed13-Apr-12 2:47 
GeneralMy vote of 5 Pin
Cristian Mocho29-Aug-11 6:02
memberCristian Mocho29-Aug-11 6:02 
QuestionThe type or namespace name 'Picture' could not be found (are you missing a using directive or an assembly reference) Pin
Saching201011-Jul-11 23:09
memberSaching201011-Jul-11 23:09 
GeneralI can't get the path Pin
Arun K V7-Dec-10 1:35
memberArun K V7-Dec-10 1:35 
GeneralMy vote of 1 Pin
dreadread1221-Sep-10 22:36
memberdreadread1221-Sep-10 22:36 
GeneralMy vote of 1 Pin
Wyrm_UK15-Sep-10 10:18
memberWyrm_UK15-Sep-10 10:18 
General[My vote of 1] confirmed AnoopSihag findings (only works if server is localhost) Pin
uofakron25-Apr-09 13:50
memberuofakron25-Apr-09 13:50 
GeneralHi to use the picture please create a dll named stdole.dll and add it Pin
Naresnkumar28-Feb-09 0:11
memberNaresnkumar28-Feb-09 0:11 
GeneralMy vote of 1 Pin
Member 365878830-Dec-08 20:31
memberMember 365878830-Dec-08 20:31 
QuestionI WANT KNOW HOW CAN WRITE THE PATH AND THERE'S EXAMPLE SHOW WHAT I NEED? Pin
NG_MIDO24-Dec-08 11:56
memberNG_MIDO24-Dec-08 11:56 
Questionabout CallServer(); Pin
vvttrryy18-Nov-08 0:23
membervvttrryy18-Nov-08 0:23 
GeneralUpload from Server.. Pin
Abhishek Sur10-Nov-08 2:12
memberAbhishek Sur10-Nov-08 2:12 
GeneralSomething is Missing Whcih Make it Poor Pin
AnoopSihag26-May-08 6:12
memberAnoopSihag26-May-08 6:12 
QuestionAre there something wrong? Pin
phuong1713-Apr-08 22:20
memberphuong1713-Apr-08 22:20 
QuestionAdding a caption box and storing values in database Pin
gnasdaq8-Oct-07 16:12
membergnasdaq8-Oct-07 16:12 
GeneralThanks so much!!! Pin
Garwick26-Aug-07 13:46
memberGarwick26-Aug-07 13:46 
GeneralRe: Thanks so much!!! Pin
microsoft_tony23-Feb-08 17:59
membermicrosoft_tony23-Feb-08 17:59 
GeneralMissing picture class Pin
Karsten Brocksieper14-Mar-07 2:03
memberKarsten Brocksieper14-Mar-07 2:03 
GeneralRe: Missing picture class Pin
KnightWing193-Dec-08 6:24
memberKnightWing193-Dec-08 6:24 
GeneralThank You Pin
binstar18-Feb-07 12:21
memberbinstar18-Feb-07 12:21 
GeneralCompletely Non-functional Pin
aprenot17-Jan-07 9:55
memberaprenot17-Jan-07 9:55 
GeneralRe: Completely Non-functional Pin
aprenot17-Jan-07 9:59
memberaprenot17-Jan-07 9:59 
GeneralRe: Completely Non-functional Pin
azamsharp17-Jan-07 10:13
memberazamsharp17-Jan-07 10:13 
GeneralRe: Completely Non-functional Pin
azamsharp17-Jan-07 10:54
memberazamsharp17-Jan-07 10:54 
GeneralUpload Animation Pin
azamsharp17-Jan-07 5:06
memberazamsharp17-Jan-07 5:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160721.1 | Last Updated 17 Jan 2007
Article Copyright 2007 by azamsharp
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid