Monday, August 2, 2010

Silverlight File upload


    I tried searching for a simple file upload control for silverlight 4 and came across some excellent multi-file upload controls specially the one from codeplex "http://silverlightfileupld.codeplex.com/ ", but that is not what I needed due to complexity or the difficulty of code editing or changing to adjust according to my project .So I began in my personal file uploader as the following ,


  1. Open file dialogue to get the file,
  2. public OpenFileDialog fileDialog = null;

    fileDialog.Multiselect = false; // one file at a time

    fileDialog.Filter = ""; // Add file filter


  3. SVC web service to write the file to the server
  4. namespace FileUpload.Web

    {

    [ServiceContract(Namespace = "")]

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

    public class FileWriteWSer

    {

    [OperationContract]

    public void SaveFile(UploadFile UploadFile)

    {

    FileStream FileStream = new FileStream("C:\\Uploadedfiles" + UploadFile.FileName, FileMode.Append); // change it or make it configurable

    FileStream.Write(UploadFile.File, 0, UploadFile.File.Length);

    FileStream.Close();

    FileStream.Dispose();

    }

    }

    // This class is the data contract class to transfer file stream blocks between server and client .

    [DataContract]

    public class UploadBacket

    {

    [DataMember]

    public string FileName; // in which backet is added.

    [DataMember]

    public byte[] File; // buffer to write in the end of the file.

    }

    }


  5. Why did we transfer file into blocks not as a single block?
  6. The answer to this question is initially due to the property maxBufferSize="214748647" In the web service configuration file which this is the maximum integer value can be set to.then to make it more the file uploader more flexible for enhancement like multifile upload or pause resume option.


  7. Handle file blocks server transfer.
  8. bool? retval = fileDialog.ShowDialog();

    if (retval != null && retval == true)

    {

    Stream strm = fileDialog.File.OpenRead();

    byte[] Buffer = new byte[strm.Length];

    strm.Read(Buffer, 0, (int)strm.Length);

    strm.Dispose();

    strm.Close();

    webser.UploadBacket file = new SerRef.UploadBacket ();

    file.FileName = fileDialog.File.Name;

    byte[] bufferSegment = new byte[15000];

    proxy.SaveFileCompleted += new EventHandler(proxy_SaveFileCompleted);

    int segments = (Buffer.Length / bufferSegment.Length);

    int remainder = (Buffer.Length % bufferSegment.Length);

    if(Buffer.Length>15000) // max file block size

    {

    for (int j = 0; j <= segments - 1; j++)

    {

    bufferSegment = new byte[15000];

    for (int i = 0; i <>

    {

    bufferSegment[i] = Buffer[15000*j+i];

    }

    file.File = bufferSegment;

    proxy.SaveFileAsync(file);

    }

    bufferSegment = new byte[remainder];

    for (int i = 0; i <>

    {

    bufferSegment[i] = Buffer[15000 * segments + i];

    }

    file.File = bufferSegment;

    fileIsFinished = true;

    proxy.SaveFileAsync(file);

    }

    }

    void proxy_SaveFileCompleted(object sender,System.ComponentModel.AsyncCompletedEventArgs e)

    {

    // Here to add onReturn code

    }


Thank you,
Sj

2 comments: