Asychronously upload a file using jQuery to a Web API controller

Here’s the code for the HTML5 form:

<form id="upload">
    <div>
        <label for="myFile"></label>
        <div>
            <input type="file" id="myFile" />
        </div>
    </div>
    <button type="submit">Upload</button>
</form>

We need to use jQuery to handle when the user submits the upload, to make sure it gets handled asynchronously and posted to our Web API controller:

        // Hook into the form's submit event.
        $('#upload').submit(function () {

            // To keep things simple in this example, we'll
            // use the FormData XMLHttpRequest Level 2 object (which
            // requires modern browsers e.g. IE10+, Firefox 4+, Chrome 7+, Opera 12+ etc).
            var formData = new FormData();

            // We'll grab our file upload form element (there's only one, hence [0]).
            var opmlFile = $('#opmlFile')[0];

            // If this example we'll just grab the one file (and hope there's at least one).
            formData.append("opmlFile", opmlFile.files[0]);

            // Now we can send our upload!
            $.ajax({
                url: 'api/upload', // We'll send to our Web API UploadController
                data: formData, // Pass through our fancy form data

                // To prevent jQuery from trying to do clever things with our post which
                // will break our upload, we'll set the following to false
                cache: false,
                contentType: false,
                processData: false,

                // We're doing a post, obviously.
                type: 'POST',

                success: function () {
                    // Success!
                    alert('Woot!');
                }
            });

            // Returning false will prevent the event from
            // bubbling and re-posting the form (synchronously).
            return false;
        });


Ok and now in our controller, we can deal with the uploaded file(s):

    using System;
    using System.IO;
    using System.Net;
    using System.Net.Http;
    using System.Web;
    using System.Web.Http;

    class UploadController : ApiController
    {
        public async void Post()
        {
            if (!Request.Content.IsMimeMultipartContent())
            {
                throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
            }

            // We'll store the uploaded files in an Uploads folder under the web app's App_Data special folder
            var streamProvider = new MultipartFormDataStreamProvider(HttpContext.Current.Server.MapPath("~/App_Data/Uploads/"));

            // Once the files have been written out, we can then process them.
            await Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith(t =>
            {
                if (t.IsFaulted || t.IsCanceled)
                {
                    throw new HttpResponseException(HttpStatusCode.InternalServerError);
                }

                // Here we can iterate over each file that got uploaded.
                foreach (var fileData in t.Result.FileData)
                {
                    // Some good things to do are to check the MIME type before we do the processing, e.g. for XML:
                    if (fileData.Headers.ContentType.MediaType.Equals("text/xml", StringComparison.InvariantCultureIgnoreCase))
                    {
                        // And this is how we can read the contents (note you would probably want to do this asychronously
                        // but let's try keep things simple for now).
                        string contents = File.ReadAllText(fileData.LocalFileName);
                    }
                }
            });
        }
    }

Uninstalling VMWare Workstation when Hyper-V is installed

Well, it was annoying enough that VMWare doesn’t launch on my machine when Hyper-V is installed. I’m skeptical that VMWare wouldn’t run if Hyper-V isn’t running at the same time, and this check just reeks of anti-competition.

Unfortunately for VMWare, that can work against them rather than encourage me to uninstall Hyper-V. That means I’m ditching them for now (mainly as Visual Studio integration with Hyper-V for things like Windows 8 and Windows Phone 8 development is good; not to mention, Hyper-V is built in and doesn’t cost extra).

I went to uninstall VMWare today but got this error:

image

Wow! Talk about pain in the ass.

Fortunately a quick search later, Jussi Palo has a simple solution, altering the installer’s lua script to skip this check:

Remove VMware Workstation or Player when Hyper-V is installed

And now I can uninstall.