Uploading a File Using ASP.NET Web API RC

In this post I’m going show an example of uploading a file into a directory on the server using ASP.NET Web API RC. You can download the package from NuGet or MVC 4 from the ASP.NET site.

To begin, add a new ASP.NET MVC 4 Project, and select Web API as the project template. Add a new View (or modify an existing one) to contain the following HTML.

<h2>

Upload a File</h2>

<p>

    File to Upload:<br />

    <form enctype=”multipart/form-data”>

    <input id=”fileinput1″ type=”file” name=”file” />

    </form>

</p>

<p>

    New File Name:<br />

    <input type=”text” id=”txtNewFileName” />

</p>

<p>

    Folder to save in:<br />

    <select id=”ddlFolders”></select>

</p>

<p>

    <input type=”button” id=”btnUpload” value=”Upload” onclick=”upload()” />

</p>

    <div id=”divResult” />

We need to populate the dropdown with the directories on our server. Of course, we’ll use Web API for that.

Add a new Web API Controller Class to your solution and name it FilesController.cs. Add a new Action, called GetDirectories().

public List<string> GetDirectories()

{

    var directories = new List<string>();

    Directory.GetDirectories(HttpContext.Current.Server.MapPath(“~/”)).ToList().ForEach(d => directories.Add((new DirectoryInfo(d)).Name));

    return new List<string>(directories);

}

We’ll use jQuery to get the Response. Make sure you have your jQuery script references, and add the following jQuery code, which will loop through the directory names  and add each one to the drop down.

<script type=”text/javascript”>

    $(document).ready(function () {

        $.getJSON(“api/files/getdirectories,

                    function (data) {

                        var items;

                        $.each(data, function (key, val) {

                            items += “<option value='” + val + “‘>” + val + “</option>”;

                        });

                        $(‘#ddlFolders’).html(items);

                    });

   });

</script>

Hit F5 to run your application. Notice the DropDown populated with the directories. If you take a look in Fiddler, you should be able to see the GetDirectories() action being hit, with the JSON string values being returned.

Fiddler View

The last step is to POST the file to the Web API and save it in the selected directory as the specified file name.

It actually  pays to give the user the option to rename the file, as in RC, the file is saved as a random string such as “BodyPart_10cfd996-ff7b-46e2-b0a4-dae46abbe765″. See my question on SO, to which Henrik F. Nielsen and Filip W. thankfully responded. (Follow them on twitter for great Web API info/updates.) You would want to rename the file either way with the correct extension.

Here’s the UploadFile Action, which takes in two parameters named “folder” and “newFileName” that will be coming from the URI.

public Task<HttpResponseMessage> UploadFile([FromUri]string folder, [FromUri]string newFileName)

{

if (!Request.Content.IsMimeMultipartContent())

{

throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.UnsupportedMediaType));

}


// Save file

string path = HttpContext.Current.Server.MapPath(string.Format(“~/{0}”, folder));

MultipartFormDataStreamProvider provider = new MultipartFormDataStreamProvider(path);

var task = Request.Content.ReadAsMultipartAsync(provider);


// Log exceptions

task.ContinueWith(t =>

{

if (t.IsFaulted)

{

// Log t.Exception

}

});


return
task.ContinueWith<HttpResponseMessage>(t =>

{

var bodyPart = provider.BodyPartFileNames.FirstOrDefault();

string savedFile = bodyPart.Value;

string originalFile = bodyPart.Key.TrimStart(‘”‘).TrimEnd(‘”‘);

string newFile = string.Format(“{0}{1}”, newFileNamePath.GetExtension(originalFile));


// Copy file and rename with new file name and correct extension

        FileInfo file = new FileInfo(savedFile);

        file.CopyTo(Path.Combine(path, newFile), true);

        file.Delete();


// Return ResponseMessage

         return new HttpResponseMessage()

{

Content = new StringContent(string.Format(“File saved in {0} as {1}.”, folder, newFile))

};

}, TaskScheduler.FromCurrentSynchronizationContext());

}

To call the UploadAction, add the following jQuery button click function.

$(‘#btnUpload’).click(function () {

    $(“#divResult”).html(“Uploading…”);

    var formData = new FormData($(‘form’)[0]);

    $.ajax({ url: ‘api/files/uploadfile?folder=’ + $(‘#ddlFolders’).val() + ‘&newfileName=’ + $(‘#txtNewFileName’).val(),

        type: ‘POST’,

        success: function (data) {

            $(“#divResult”).html(data);

        },

        data: formData,

        cache: false,

        contentType: false,

        processData: false

    });

});

Here we’re calling UploadFile(), passing along the folder and newFileName. The div will show “Uploading…”, and upon a successful response, it will display where the file has been saved. Again, fiddler would show you the request and response details.

*Note, I’m using the FormData element here, which is currently not supported in IE (9) (and, if I’m not mistaken, Opera). An alternative would be post the form with the jQuery Form Plugin

You can now run your application and try it out! You should be able to see the file in your directory.

Uploading a file

File in directory

I hope this post helps other Web API beginners who like me are just starting to play around with it. Comments are welcome, and thanks for reading!

About these ads

3 thoughts on “Uploading a File Using ASP.NET Web API RC

  1. samir says:

    getting error like that and how to resolve that?

    Error 3 ‘System.Net.Http.MultipartFormDataStreamProvider’ does not contain a definition for ‘BodyPartFileNames’ and no extension method ‘BodyPartFileNames’ accepting a first argument of type ‘System.Net.Http.MultipartFormDataStreamProvider’ could be found (are you missing a using directive or an assembly reference?) D:\RestApi\APISample\FileUploadWebAPI\FileUploadWebAPI\Controllers\FilesController.cs 43 66 FileUploadWebAPI

Leave a reply.

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s