Permalink
Fetching contributors…
Cannot retrieve contributors at this time
98 lines (58 sloc) 4.94 KB
uid title author description ms.author ms.date ms.assetid msc.legacyurl msc.type
web-api/overview/advanced/sending-html-form-data-part-2
Sending HTML Form Data in ASP.NET Web API: File Upload and Multipart MIME | Microsoft Docs
MikeWasson
riande
06/21/2012
a7f3c1b5-69d9-4261-b082-19ffafa5f16a
/web-api/overview/advanced/sending-html-form-data-part-2
authoredcontent

Sending HTML Form Data in ASP.NET Web API: File Upload and Multipart MIME

by Mike Wasson

Part 2: File Upload and Multipart MIME

This tutorial shows how to upload files to a web API. It also describes how to process multipart MIME data.

[!NOTE] Download the completed project.

Here is an example of an HTML form for uploading a file:

[!code-htmlMain]

This form contains a text input control and a file input control. When a form contains a file input control, the enctype attribute should always be "multipart/form-data", which specifies that the form will be sent as a multipart MIME message.

The format of a multipart MIME message is easiest to understand by looking at an example request:

[!code-consoleMain]

This message is divided into two parts, one for each form control. Part boundaries are indicated by the lines that start with dashes.

[!NOTE] The part boundary includes a random component ("41184676334") to ensure that the boundary string does not accidentally appear inside a message part.

Each message part contains one or more headers, followed by the part contents.

  • The Content-Disposition header includes the name of the control. For files, it also contains the file name.
  • The Content-Type header describes the data in the part. If this header is omitted, the default is text/plain.

In the previous example, the user uploaded a file named GrandCanyon.jpg, with content type image/jpeg; and the value of the text input was "Summer Vacation".

File Upload

Now let's look at a Web API controller that reads files from a multipart MIME message. The controller will read the files asynchronously. Web API supports asynchronous actions using the task-based programming model. First, here is the code if you are targeting .NET Framework 4.5, which supports the async and await keywords.

[!code-csharpMain]

Notice that the controller action does not take any parameters. That's because we process the request body inside the action, without invoking a media-type formatter.

The IsMultipartContent method checks whether the request contains a multipart MIME message. If not, the controller returns HTTP status code 415 (Unsupported Media Type).

The MultipartFormDataStreamProvider class is a helper object that allocates file streams for uploaded files. To read the multipart MIME message, call the ReadAsMultipartAsync method. This method extracts all of the message parts and writes them into the streams provided by the MultipartFormDataStreamProvider.

When the method completes, you can get information about the files from the FileData property, which is a collection of MultipartFileData objects.

  • MultipartFileData.FileName is the local file name on the server, where the file was saved.
  • MultipartFileData.Headers contains the part header (not the request header). You can use this to access the Content_Disposition and Content-Type headers.

As the name suggests, ReadAsMultipartAsync is an asynchronous method. To perform work after the method completes, use a continuation task (.NET 4.0) or the await keyword (.NET 4.5).

Here is the .NET Framework 4.0 version of the previous code:

[!code-csharpMain]

Reading Form Control Data

The HTML form that I showed earlier had a text input control.

[!code-htmlMain]

You can get the value of the control from the FormData property of the MultipartFormDataStreamProvider.

[!code-csharpMain]

FormData is a NameValueCollection that contains name/value pairs for the form controls. The collection can contain duplicate keys. Consider this form:

[!code-htmlMain]

The request body might look like this:

[!code-consoleMain]

In that case, the FormData collection would contain the following key/value pairs:

  • trip: round-trip
  • options: nonstop
  • options: dates
  • seat: window