Upload any type of File through a C# Web Service

Introduction

This article shall describe an approach that may be used to upload any sort of a file through a web service from a Windows Forms application. The approach demonstrated does not rely on the ASP.NET file uploader control and allows the developer the opportunity to upload files programmatically and without user intervention. Such an approach may be useful for doing something like processing out the contents of a local message queue when internet service is available (if the user base were mobile and had only intermittent connectivity). The article also addresses the use of a file size check as a precursor to allowing a file to upload through the service.

img1.jpg

Figure 1: Test Application Shown Uploading a File.

img2.jpg

Figure 2: Mixed bag of different file types in transient storage folder.

Getting Started

The solution contains two projects; one is an ASP.NET Web Service project (Uploader) and the other is a Win Forms test application (TestUploader) used to demonstrate uploading files through the web method provided in the web service project.

The web service project contains only a single web service (FileUploader) which in turn contains only a single Web Method (UploadFile). The Win Forms application contains only a single form which contains the controls (one textbox and two buttons used in conjunction with an OpenFileDialog control) and code necessary to select and upload files through the web service.

img3.jpg

Figure 3: Solution Explorer with the both Projects Visible.

Code:  Uploader Web Service Project

The Uploader web service project is an ASP.NET web service project containing a single web service called, “FileUploader”; this web service exposes a single web method called, “UploadFile”.

The code for this web service begins with the following:

  1. using

     System;  

  2. using

     System.Data;  

  3. using

     System.Web;  

  4. using

     System.Collections;  

  5. using

     System.Web.Services;  

  6. using

     System.Web.Services.Protocols;  

  7. using

     System.ComponentModel;  

  8. using

     System.IO;   

  9. namespace

     Uploader  

  10. {  

  11.     

      

  12.     

      

  13.     

      

  14.     

      

  15.     

      

  16.     [WebService(Namespace = 

    “http://tempuri.org/”

    )]  

  17.     [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]  

  18.     [ToolboxItem(

    false

    )]  

  19.     

    public

     

    class

     FileUploader : System.Web.Services.WebService  

  20.     {  

The class starts out with the default imports; I added System.IO to the defaults to support the use of file and memory streams. The web service namespace is left as the default http://tempuri.org/ which of course will have to updated if the service were deployed.

The remainder of the code supplied in this class is used to define the web method used to upload the file; the code is annotated. The essential process is that, files converted to byte arrays are passed along with the full name of the file (not the path) including the extension as arguments to the UploadFile web method. The byte array is passed to a memory stream, and a file stream is opened pointing to a newly created file (named the name of the original file) within the target folder used to store the files. Once the file stream has been created, the memory stream is written into the file stream and then the memory stream and file stream are disposed of. 

The web method is setup to return a string; if all goes well, the string returned will read, “OK”, if not, the error message encountered will be returned to the caller.

  1. [WebMethod]  

  2. public

     

    string

     UploadFile(

    byte

    [] f, 

    string

     fileName)  

  3. {  

  4.     

      

  5.     

      

  6.     

      

  7.     

    try

      

  8.     {  

  9.         

      

  10.         

      

  11.         MemoryStream ms = 

    new

     MemoryStream(f);  

  12.         

      

  13.         

      

  14.         

      

  15.         FileStream fs = 

    new

     FileStream(System.Web.Hosting.HostingEnvironment.MapPath  

  16.                     (

    “~/TransientStorage/”

    ) +fileName, FileMode.Create);   

  17.         

      

  18.         

      

  19.         ms.WriteTo(fs);  

  20.         

      

  21.         ms.Close();  

  22.         fs.Close();  

  23.         fs.Dispose();  

  24.         

      

  25.         

    return

     

    “OK”

    ;  

  26.     }  

  27.     

    catch

     (Exception ex)  

  28.     {  

  29.         

      

  30.         

    return

     ex.Message.ToString();  

  31.     }  

  32. }  

Code:  Test Uploader Win Forms Application

The test application contains a single Windows Form class; this form contains a text box used to display the name of the file selected for upload, a browse button used to launch an open file dialog box which is used to navigate to and select a file for upload, and an upload button which is used to pass the file to web service so that the selected file may be stored on the server.

The code for this class begins with the following:

  1. using

     System;  

  2. using

     System.Collections.Generic;  

  3. using

     System.ComponentModel;  

  4. using

     System.Data;  

  5. using

     System.Drawing;  

  6. using

     System.Text;  

  7. using

     System.Windows.Forms;  

  8. using

     System.IO;  

  9. namespace

     TestUploader  

  10. {  

  11.     

      

  12.     

      

  13.     

      

  14.     

      

  15.     

    public

     partial 

    class

     Form1 : Form  

  16.     {  

  17.         

    public

     Form1()  

  18.         {  

  19.             InitializeComponent();  

  20.         }   

  21.         

    private

     

    void

     Form1_Load(

    object

     sender, EventArgs e)  

  22.         {  

  23.             

      

  24.         }  

Aside from the default imports, I have added only System.IO to the list. This being necessary to support working with files. The namespace and class declarations are in the default configuration. In addition to System.IO, the project also adds in a web reference pointing to the File Uploader web service, the reference is given the alias of Uploader.

The next bit of code in the class is private method used to prepare the file for submittal to the web service and to actually make that submittal. The code below is annotated to describe the activity but the essential parts of the operation are to check the file size to see if the web service will accept the file (by default, the web server will accept uploads smaller than 4 MB in size, the web config file must be updated in order to support larger uploads), and to convert the file to a byte array. When everything is ready, the byte array and the name of the file including the extension is passed to an instance of the web service web method. 

Note that, when setting up the demo, you will have remove and add the web reference back into the project in order for it to work for you.

  1.   

  2.   

  3.   

  4.   

  5.   

  6.   

  7. private

     

    void

     UploadFile(

    string

     filename)  

  8. {  

  9.     

    try

      

  10.     {  

  11.         

      

  12.         String strFile = System.IO.Path.GetFileName(filename);  

  13.         

      

  14.         TestUploader.Uploader.FileUploader srv = 

    new

      

  15.         TestUploader.Uploader.FileUploader();  

  16.         

      

  17.         FileInfo fInfo = 

    new

     FileInfo(filename);  

  18.         

      

  19.         

      

  20.         

    long

     numBytes = fInfo.Length;  

  21.         

    double

     dLen = Convert.ToDouble(fInfo.Length / 1000000);  

  22.         

      

  23.         

      

  24.         

      

  25.         

    if

     (dLen < 4)  

  26.         {  

  27.             

      

  28.             

      

  29.             FileStream fStream = 

    new

     FileStream(filename,  

  30.             FileMode.Open, FileAccess.Read);  

  31.             BinaryReader br = 

    new

     BinaryReader(fStream);  

  32.             

      

  33.             

    byte

    [] data = br.ReadBytes((

    int

    )numBytes);  

  34.             br.Close();  

  35.             

      

  36.             

    string

     sTmp = srv.UploadFile(data, strFile);  

  37.             fStream.Close();  

  38.             fStream.Dispose();  

  39.             

      

  40.             

      

  41.             MessageBox.Show(

    “File Upload Status: “

     + sTmp, 

    “File Upload”

    );  

  42.         }  

  43.         

    else

      

  44.         {  

  45.              

      

  46.              MessageBox.Show(

    “The file selected exceeds the size limit for uploads.”

    “File Size”

    );  

  47.          }  

  48.     }  

  49.     

    catch

     (Exception ex)  

  50.     {  

  51.          

      

  52.          MessageBox.Show(ex.Message.ToString(), 

    “Upload Error”

    );  

  53.     }  

  54. }  

Following the UploadFile method, the next bit of code is used to handle the browse button’s click event. This code is used merely to display an open file dialog to the user and to take the file selected through that dialog and display the file name in the form’s file name text box.

  1.   

  2.   

  3.   

  4.   

  5.   

  6. private

     

    void

     btnBrowse_Click(

    object

     sender, EventArgs e)  

  7. {  

  8.     openFileDialog1.Title = 

    “Open File”

    ;  

  9.     openFileDialog1.Filter = 

    “All Files|*.*”

    ;  

  10.     openFileDialog1.FileName = 

    “”

    ;  

  11.     

    try

      

  12.     {  

  13.         openFileDialog1.InitialDirectory = 

    “C:\\Temp”

    ;  

  14.     }  

  15.     

    catch

      

  16.     {  

  17.         

      

  18.     }  

  19.     openFileDialog1.ShowDialog();  

  20.     

    if

     (openFileDialog1.FileName == 

    “”

    )  

  21.         

    return

    ;  

  22.     

    else

      

  23.         txtFileName.Text = openFileDialog1.FileName;   

  24. }  

The class wraps up with the button click event handler for the Upload button. This handler merely checks for text in the file name text box and, if something is there, it sends the value to the Upload method.

  1.   

  2.   

  3.   

  4.   

  5.   

  6.   

  7.   

  8. private

     

    void

     btnUpload_Click(

    object

     sender, EventArgs e)  

  9. {  

  10.     

    if

     (txtFileName.Text != 

    string

    .Empty)  

  11.         UploadFile(txtFileName.Text);  

  12.     

    else

      

  13.         MessageBox.Show(

    “You must select a file first.”

    “No File Selected”

    );  

  14. }  

That wraps up all of the client and server side code necessary to upload any sort of file to a server from a Win Forms application.

Summary

This article was intended to demonstrate an easy approach to uploading any sort of a file to a web server from a Win Forms application. This example uses the default upload size of 4096 KB, if you need to upload larger files, you will need to alter this value by changing the httpRuntime maxRequestLength property to the desired value; at the same time you may need to increase the executionTimeout property to a greater value as well in order to support longer upload times. Take care when altering the values as Microsoft has established the default 4 MB limit to provide some safety against attempts to upload extremely large files that may hamper access to the server.