Tuesday, November 20, 2012

Silverlight - File Upload in Silverlight 4

In this article, i will show you how to upload file in silverlight 4 application. Uploading file is silverlight is not easy.There is no way to upload file on silverlight the way do in ASP.net.

Let see how to upload file in silverlight Application.

Step 1
Create a Silverlight application and give the solution name as SolFileUploadinSilverlight.
Select Web Project Type as ASP.NET Web site and Select Silverlight 4 version.

Step 2
Select ASP.net Web project(SolFileUploadinSilverlight.Web) and right click on web project,select Add new Folder in solution and give folder name as Images.

Step 3
On MainPage.xaml,add a button and two TextBlock control on page,it is look ike this


<UserControl x:Class="SolFileUploadinSilverlight.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition Height="12*"/>
        </Grid.RowDefinitions>
        
        <Button x:Name="btnupload" Grid.Row="0" Grid.Column="0" Width="200" Content="Upload File" HorizontalAlignment="Left" Click="btnupload_Click"></Button>
        <TextBlock x:Name="tbFileName" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock>
        <TextBlock x:Name="tbStatus" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock>
        
    </Grid>
</UserControl>




Click on image for better view

Step 4
Design Part done,now we turn on functionality part,The Idea is very simple to get file to upload from User,convert Data into stream and send to generic handler.generic handler receives that stream and writes the content to the file on the server.

On Code behind of MainPage.xaml,write a ReadWriteStream function,it is look like this 
/// <summary>
        /// Read and Write Stream of given file.
        /// </summary>
        /// <param name="Input"></param>
        /// <param name="Output"></param>
        private void ReadWriteStream(Stream Input, Stream Output)
        {
            try
            {
                byte[] ByteBufferObj = new byte[4096];
                int BytesRead = 0;

                while ((BytesRead = Input.Read(ByteBufferObj, 0, ByteBufferObj.Length)) != 0)
                {
                    Output.Write(ByteBufferObj, 0, BytesRead);
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                Input.Close();
                Output.Close();
            }
        }


In this code block we are reading the selected file in the stream and writing to the output stream. here we are creating a array of bytes with size of 4096 for uploading file in the server.if we want to upload bigger size of file then change the array of size.

Step 5
Write a UploadFile function,it is look like this
/// <summary>
        ///  Send Stream Data to the Generic handler.
        /// </summary>
        /// <param name="FileName"></param>
        /// <param name="StreamData"></param>
        /// <returns></returns>
        private Boolean UploadFile(String FileName, Stream StreamData)
        {
            Boolean Flag = false;
            try
            {
                
                Uri URIObj = Application.Current.Host.Source;

                
                UriBuilder UriBuilderObj = new System.UriBuilder(URIObj.Scheme, URIObj.Host, URIObj.Port, "FileUploadHandler.ashx");
                UriBuilderObj.Query = String.Format("FileName={0}", FileName);

                WebClient WebClientObj = new WebClient();

                WebClientObj.OpenWriteCompleted += (Sender, E) =>
                {
                    try
                    {
                        // call ReadWriteStream function
                        ReadWriteStream(StreamData, E.Result);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(ex.Message);
                    }
                    finally
                    {
                        E.Result.Close();
                        StreamData.Close();
                    }
                };

                WebClientObj.OpenWriteAsync(UriBuilderObj.Uri);

                Flag = true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            return Flag;
        }


In this Code Block,we are concat the URI of the .ashx,with name of Selected file Name.Handled the OpenWriteCompleted event and using lamda expression defining the code that runs when this event fires.We are calling OpenWriteAsync method by passing the uri of the generic handler (.ashx) that actually opens and starts writing data to the handler and when it completes the OpenWriteCompleted event fires and start writing the selected file to the output stream(Call ReadWrite function in OpenWriteCompleted Event). This method calls the generic handler because of Uri into OpenWriteAsync method. 

Step 6
Write a GetFile function,it is look like this
/// <summary>
        /// get selected file from user and upload to the server.
        /// </summary>
        private void GetFile()
        {
            Boolean? IsOpen = false;
            try
            {
                OpenFileDialog OFDobj = new OpenFileDialog();
                OFDobj.Filter = "All files (*.*)|*.*|JPG Images (*.jpg)|*.jpg";
                OFDobj.Multiselect = false;

                IsOpen = OFDobj.ShowDialog();

                if (IsOpen == true)
                {
                    try
                    {
                        if (UploadFile(OFDobj.File.Name, OFDobj.File.OpenRead()))
                        {
                            tbFileName.Text = OFDobj.File.Name;
                            tbFileName.Foreground = new SolidColorBrush(Colors.Green);

                            tbStatus.Text = "File Upload Sucessfully";
                            tbStatus.Foreground = new SolidColorBrush(Colors.Green);
                        }
                        else
                        {
                            tbStatus.Text = "Error Occurred on file uploading";
                            tbStatus.Foreground = new SolidColorBrush(Colors.Red);
                        }
                    }
                    catch(Exception)
                    {
                         tbStatus.Text = "Error Occurred on file uploading";
                         tbStatus.Foreground = new SolidColorBrush(Colors.Red);
                    }
                }
                else
                {
                    tbStatus.Text = "Select File for Uploding file";
                    tbStatus.Foreground = new SolidColorBrush(Colors.Red);
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message); 
            }
        }


In this Code block,we have used OpenFileDialog class to open the selected file dialog box and call UploadFile Function to send Data to the Generic Handler.

Step 7
Call GetFile Function on Button Upload Click event,it is look like this

private void btnupload_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                GetFile();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);  
            }
        }



Full Code Behind of MainPage
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SolFileUploadinSilverlight
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();

        }

        #region Methods

        /// <summary>
        /// Read and Write Stream of given file.
        /// </summary>
        /// <param name="Input"></param>
        /// <param name="Output"></param>
        private void ReadWriteStream(Stream Input, Stream Output)
        {
            try
            {
                byte[] ByteBufferObj = new byte[4096];
                int BytesRead = 0;

                while ((BytesRead = Input.Read(ByteBufferObj, 0, ByteBufferObj.Length)) != 0)
                {
                    Output.Write(ByteBufferObj, 0, BytesRead);
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                Input.Close();
                Output.Close();
            }
        }

        /// <summary>
        ///  Send Stream Data to the Generic handler.
        /// </summary>
        /// <param name="FileName"></param>
        /// <param name="StreamData"></param>
        /// <returns></returns>
        private Boolean UploadFile(String FileName, Stream StreamData)
        {
            Boolean Flag = false;
            try
            {
                
                Uri URIObj = Application.Current.Host.Source;

                
                UriBuilder UriBuilderObj = new System.UriBuilder(URIObj.Scheme, URIObj.Host, URIObj.Port, "FileUploadHandler.ashx");
                UriBuilderObj.Query = String.Format("FileName={0}", FileName);

                WebClient WebClientObj = new WebClient();

                WebClientObj.OpenWriteCompleted += (Sender, E) =>
                {
                    try
                    {
                        // call ReadWriteStream function
                        ReadWriteStream(StreamData, E.Result);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(ex.Message);
                    }
                    finally
                    {
                        E.Result.Close();
                        StreamData.Close();
                    }
                };

                WebClientObj.OpenWriteAsync(UriBuilderObj.Uri);

                Flag = true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            return Flag;
        }

        /// <summary>
        /// get selected file from user and upload to the server.
        /// </summary>
        private void GetFile()
        {
            Boolean? IsOpen = false;
            try
            {
                OpenFileDialog OFDobj = new OpenFileDialog();
                OFDobj.Filter = "All files (*.*)|*.*|JPG Images (*.jpg)|*.jpg";
                OFDobj.Multiselect = false;

                IsOpen = OFDobj.ShowDialog();

                if (IsOpen == true)
                {
                    try
                    {
                        if (UploadFile(OFDobj.File.Name, OFDobj.File.OpenRead()))
                        {
                            tbFileName.Text = OFDobj.File.Name;
                            tbFileName.Foreground = new SolidColorBrush(Colors.Green);

                            tbStatus.Text = "File Upload Sucessfully";
                            tbStatus.Foreground = new SolidColorBrush(Colors.Green);
                        }
                        else
                        {
                            tbStatus.Text = "Error Occurred on file uploading";
                            tbStatus.Foreground = new SolidColorBrush(Colors.Red);
                        }
                    }
                    catch(Exception)
                    {
                         tbStatus.Text = "Error Occurred on file uploading";
                         tbStatus.Foreground = new SolidColorBrush(Colors.Red);
                    }
                }
                else
                {
                    tbStatus.Text = "Select File for Uploding file";
                    tbStatus.Foreground = new SolidColorBrush(Colors.Red);
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message); 
            }
        }

        #endregion

        private void btnupload_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                GetFile();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);  
            }
        }

       
    }
}


Step 8
Now Create a Generic Handler in ASP.net Web project(SolFileUploadinSilverlight.Web),Select SolFileUploadinSilverlight.Web Solution,Right Click on Solution,Select Add new Item  from Context menu,Select Generic Handler from Template and Rename the file name as FileUploadHandler.ashx,Click on Add button,it is look like this




Click on image for better view

Step 9
In Generic handler, write SaveFileInServer function,it is look like this 
/// <summary>
    /// Save file in Images Folder
    /// </summary>
    /// <param name="StreamObj"></param>
    /// <param name="FsObj"></param>
    private void SaveFileInServer(Stream StreamObj, FileStream FsObj)
    {
        try
        {
            byte[] ByteBufferObj = new byte[4096];
            int BytesRead = 0;

            while ((BytesRead = StreamObj.Read(ByteBufferObj, 0, ByteBufferObj.Length)) != 0)
            {
                FsObj.Write(ByteBufferObj, 0, BytesRead);
            }
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message);
        }
        finally
        {
            StreamObj.Close();
            FsObj.Close();
        }
    }


In this Code Block,We are reading the input steam into array of bytes and writing to the file.

Step 10
On ProcessRequest function,write a below code,it is look like this
public void ProcessRequest (HttpContext context) {

        try
        {
            String FileName = context.Request.QueryString["FileName"].ToString();

            if (FileName != String.Empty)
            {
                FileStream FSobj = File.Create(context.Server.MapPath("~/Images/" + FileName));

                SaveFileInServer(context.Request.InputStream, FSobj);
            }
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message); 
        }
        
    }


In this Code block,we are first retrieving the file name being passed from the querystring.we are using FileStream to create a file based on the file name being passed here and call SavefileInServer function.

Note:

  • We are also passing the folder name – Images where our files gets uploaded.
  • we must have write permission to this folder.

Full Code of Generic Handler
<%@ WebHandler Language="C#" Class="FileUploadHandler" %>

using System;
using System.Web;
using System.IO;

public class FileUploadHandler : IHttpHandler {
    
    public void ProcessRequest (HttpContext context) {

        try
        {
            String FileName = context.Request.QueryString["FileName"].ToString();

            if (FileName != String.Empty)
            {
                FileStream FSobj = File.Create(context.Server.MapPath("~/Images/" + FileName));

                SaveFileInServer(context.Request.InputStream, FSobj);
            }
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message); 
        }
        
    }

    #region Methods

    /// <summary>
    /// Save file in Images Folder
    /// </summary>
    /// <param name="StreamObj"></param>
    /// <param name="FsObj"></param>
    private void SaveFileInServer(Stream StreamObj, FileStream FsObj)
    {
        try
        {
            byte[] ByteBufferObj = new byte[4096];
            int BytesRead = 0;

            while ((BytesRead = StreamObj.Read(ByteBufferObj, 0, ByteBufferObj.Length)) != 0)
            {
                FsObj.Write(ByteBufferObj, 0, BytesRead);
            }
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message);
        }
        finally
        {
            StreamObj.Close();
            FsObj.Close();
        }
    }
    
    #endregion

    public bool IsReusable {
        get {
            return false;
        }
    }

}


Run the project.

Output



Download
Download Source Code

No comments:

Post a Comment