logo

File Upload Control Using Silverlight

By Vasanthakumar D
Printer Friendly Version
View My Articles
1380 Views
    

Uploading files in web application is always a big trouble. We need to take care of the file size before upload the files into the server. And to check the file size at client side itself, we need to go for ActiveX controls which is not secured and also not cross browser supported. The same will be a big issue for Multiple file upload control. So, I have used Silverlight controls for uploading files. The files transfer will be taken care of by Webservices.


Here is the Code for the controls....

XAML

<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"  xmlns:basics="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"  x:Class="SilverlightApplication1.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="600" Width="800" >

    <Grid x:Name="LayoutRoot" Background="YellowGreen" ShowGridLines="True" >
        <Grid.RowDefinitions>
            <RowDefinition Height="535"></RowDefinition>
            <RowDefinition Height="30"></RowDefinition>
            <RowDefinition Height="35"></RowDefinition>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="2" Orientation="Horizontal" >
            <Button Content="Choose File" x:Name="MyButton" Width="100" Height="20" Click="Mybutton_Click" Grid.Column="0"></Button>
            <Button Content="Reset" x:Name="MyReset" Width="100" Height="20" Click="MyReset_Click" Grid.Column="1"></Button>
            <Button Content="Upload" x:Name="Upload" Width="100" Height="20" Click="Upload_Click"  Grid.Column="2"></Button>
        </StackPanel>
        <StackPanel Grid.Row="1" VerticalAlignment="Center">
          <ProgressBar Name="progFile" Height="20" Width="800"></ProgressBar>
        </StackPanel>
        <Grid Grid.Row="0">
            <data:DataGrid Name="FileList" LoadingRow="DataGrid_LoadingRow">
            </data:DataGrid>
        </Grid>
    </Grid>
</UserControl>

you can see that you have three buttons,
1.Choose File   - to borwse the file using file upload dialog
2. Reset - to remove all selections of files
3. Upload - to upload the selected files into the server

and one datagrid, to show the list of selected of files on the fly...
here is the screen  shot for this

and one progress bar to show the progress of the file uploading...



 
When ever you select the Choose file button, it will show the file browser dialog and you can select files from client file system. I have checked the individual file limit as 1MB.

I have used the class file to store the file related informations. For each file I have created one file class object and I added the file object to Arraylist.

here is the file class code

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;

namespace SilverlightApplication1
{
    public class FilesClass
    {
        public FilesClass()
        {
            //do nothing
        }

        string strStatus = "";
        string strNo = "";
        FileInfo strFileName = null;

        //for file serial number
        public string PropNumber
        {
            get
            {
                return strNo;
            }
            set
            {
                strNo = value;
            }
        }

        //to store the file
        public FileInfo PropFileName
        {
            get
            {
                return strFileName;
            }
            set
            {
                strFileName = value;
            }
        }

       //to store the status, whether file uploaded successfully or not  
        public string PropStatus
        {
            get
            {
                return strStatus;
            }
            set
            {
                strStatus = value;
            }
        }
    }
}







and here is the Choose button click event code..

private void Mybutton_Click(object sender, RoutedEventArgs e)
        {
            //show the file browser dialog to select file
            OpenFileDialog op = new OpenFileDialog();
            op.ShowDialog();
            if (op.File != null && op.File.Name != "")
            {
                //check the file size. It shoud be less than 1MB
                if (op.File.Length < 1048576)
                {
                    //flAll[iFileCount] = op.File;
                    //fl.Add(op.File);
                    
                    //create a new fill class object to maintain the file content    
                    FilesClass obj = new FilesClass();
                   //assign file   
                    obj.PropFileName = op.File;
                    //assing file number
                    obj.PropNumber = iFileCount.ToString();
                    //add the file object to files list collection  
                    fl.Add(obj);

                    //flNames.Add(op.File.Name);
                    
                    //update the grid with new files
                    BindGrid();

                    iFileCount++;
                }
                else
                {
                    MessageBox.Show("Max file size is 1 MB");
                }
            }
            else
            {
                MessageBox.Show("Select File");
            }
        }

        
        //Code to bind the grid  
        private void BindGrid()
        {
            FileList.ItemsSource = null;
            //setting datasource for datagrid FileList
            FileList.ItemsSource = fl;
            FileList.SelectedIndex = -1;

            //for grid object with column header and column width
            FileList.Columns[0].Header = "S.No";
            FileList.Columns[1].Header = "File Name";
            FileList.Columns[2].Header = "Status";


            FileList.Columns[0].Width = new DataGridLength(80);
            FileList.Columns[1].Width = new DataGridLength(600);
            FileList.Columns[2].Width = new DataGridLength(100);
        }



so, when ever you select the file in browser control, it will be added to datagrid ... and you can able to see the list of selected files..

I have used Webservice to upload the file from client to server...

here is the code for this Web service


 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.IO;

namespace SilverlightApplication1.Web
{
    /// <summary>
    /// Summary description for uploadService
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class uploadService : System.Web.Services.WebService
    {

        [WebMethod]
        public string HelloWorld()
        {
            return "Hello World";
        }

//method for uplaod the files. This will be called from Silverligh code behind. 
        [WebMethod]
        public string UploadFiles(string strFileName, byte[] byFile, string strFileNo)
        {
            try
            {
                if (byFile.Length > 0)
                {
                    string strFilePath = "D:\\tmp\\" + strFileName;
                    System.IO.FileStream fs = new FileStream(strFilePath, FileMode.Create, FileAccess.Write);
                    fs.Write(byFile, 0, byFile.Length);
                    fs.Close();
                    return strFileNo;
                }
                else
                {
                    return "";
                }
            }
            catch(Exception ex)
            {
                return "";
            }
        }
    }
}

I am pasing file Name, file content as byte and file Number(serial number). Serial number will be return back to 
calling method to confirm that file uploaded successfully. As we are using Asynchronous file upload,
we need to know which file is uploading. for this I am using strFileNo in UploadFiles method.

and here is the main code for uploading files...


//we need to add web serice as Service reference in application.

//to show the progrss bar
 double progVal = 0;

        private void Upload_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (fl.Count > 0)
                {
                    progVal = (double)100 / (double)fl.Count;
//loop through the files and upload the files by passing it to web service.

                    for (int count = 0; count < fl.Count; count++)
                    {
                        ServiceReference1.uploadServiceSoapClient x = new SilverlightApplication1.ServiceReference1.uploadServiceSoapClient();

//here is the event hadndler, whihc will be invoked for every file upload
                        x.UploadFilesCompleted += new EventHandler<ServiceReference1.UploadFilesCompletedEventArgs>(UploadFileComplted);

//read the file from file class

                        FilesClass obj = (FilesClass) fl[count];
                        System.IO.FileStream str = obj.PropFileName.OpenRead();
                        byte[] by = new byte[str.Length];
                        str.Read(by, 0, by.Length);
                        str.Close();
//call the upload file methods async event, which will upload the files asynchronously
                        x.UploadFilesAsync(obj.PropFileName.Name, by, obj.PropNumber);
                        progFile.Value += progVal;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

and once the file upload complted, it will invoke the uploadfilecomplted event...



private void UploadFileComplted(object sender, ServiceReference1.UploadFilesCompletedEventArgs e)
        {
            if (e.Result != "")
            {
                //here e.Result contains the files serial number. We can change the status the file class object based on this.
                fl[Convert.ToInt32(e.Result) - 1].PropStatus = "1";
                BindGrid();
            }
        }


and to change the uploaded files status in grid, we need to use the loading row event. Depends upon the status field value, the rows back color will be changed

private void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
        {
            FilesClass obj = e.Row.DataContext as FilesClass;
            if (obj.PropStatus == "1")
            {
                e.Row.Background = new SolidColorBrush(Colors.Gray);
            }
        }

I know it will be hard to undestand the above things with out live deme... here I have attached the full sample for your better understanding...

WebSite:
http://www.eggheadcafe.com/fileupload/-1661267333_SilverlightApplication1.Web.zip

Silverlight application:
http://www.eggheadcafe.com/fileupload/-1661267333_SilverlightApplication1.zip



Didn't Find The Answer You Were Looking For?

EggHeadCafe has experts online right now that may know the answer to your question.  We pay them a bonus for answering as many questions as they can.  So, why not help them and yourself by becoming a member (free) and ask them your question right now?
Ask Question In Live Forum

If you have an OpenID and do not want to become a member of the EggHeadCafe forum, you can also sign on to Chat Chaos and post your question to our real time Silverlight chat application.
Ask Question In Chat Chaos

Article Discussion: File Upload Control Using Silverlight
Vasanthakumar D posted at Friday, May 15, 2009 8:35 AM
Original Article
 

  question on upload files
teoh denho replied to Vasanthakumar D at Monday, January 18, 2010 11:31 AM
Hi Vasanthakumar,

Im just a very beginner in silverlight and i have to develope a page about file upload. Im trying to copy paste the coding you have posted and try to figure out how it work. Unfortunately,i meet some problems in upload_click function...


ServiceReference1.uploadServiceSoapClient x = new SilverlightApplication1.ServiceReference1.uploadServiceSoapClient();

//here is the event hadndler, whihc will be invoked for every file upload
                        x.UploadFilesCompleted += new EventHandler<ServiceReference1.UploadFilesCompletedEventArgs>(UploadFileComplted);


when i copy and paste the code above into MainPage.xaml.cs file, it cannot find the "uploadServiceSoapClient".. and i get the error of this --> The type or namespace 'uploadServiceSoapClient' does not exist in the namespace 'SilverlightConnectDB.ServiceReference1' (are you missing an assembly reference?)


so what should i do to solve it?
your reply is appreciated!
 






  $1000 Contest    [)ia6l0 iii - $228  |  Jonathan VH - $161  |  Huggy Bear - $135  |  F Cali - $95  |  egg egg - $94  |  more Advertise  |  Privacy  |   (c) 2010