ASP.NET WebApi file upload implementation

Posted by Andy Feng on November 5, 2017

This article introduces how to implement file upload using Web Api 2.

Upload file(s) to a specified location of server

[Route("files")]
[HttpPost]
public async Task<FileResult> UploadFilesAsFile()
{
    // validate
    if (!Request.Content.IsMimeMultipartContent())
    {
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
    }
    // upload
    var streamProvider = new MultipartFormDataStreamProvider(@"c:\temp");
    await Request.Content.ReadAsMultipartAsync(streamProvider);

    return new FileResult
    {
        FileNames = streamProvider.FileData.Select(entry => entry.LocalFileName),
        Names = streamProvider.FileData.Select(entry => entry.Headers.ContentDisposition.FileName),
        ContentTypes = streamProvider.FileData.Select(entry => entry.Headers.ContentType.MediaType),
        Description = streamProvider.FormData["description"],
        CreatedTimestamp = DateTime.UtcNow,
        UpdatedTimestamp = DateTime.UtcNow,
    };
}

Please note that FileResult represents the return

public class FileResult
{
    public IEnumerable<string> FileNames { get; set; }
    public string Description { get; set; }
    public DateTime CreatedTimestamp { get; set; }
    public DateTime UpdatedTimestamp { get; set; }
    public IEnumerable<string> ContentTypes { get; set; }
    public IEnumerable<string> Names { get; set; }
}

Upload file(s) to the memory of server

[HttpPost]
[Route("files2")]
public async Task<FileResult> UploadFilesViaMemory()
{
    // validate
    if (!Request.Content.IsMimeMultipartContent())
    {
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
    }
    // upload
    var streamProvider = await Request.Content.ReadAsMultipartAsync();
    foreach (var httpContent in streamProvider.Contents)
    {
        using (var stream = await httpContent.ReadAsStreamAsync())
        {
            if (stream.Length == 0)
            {
                continue;
            }
            using (var fileStream = new FileStream(@"c:\temp\" + httpContent.Headers.ContentDisposition.FileName.Trim('"'), FileMode.Create, FileAccess.Write))
            {
                stream.Seek(0, SeekOrigin.Begin);
                stream.CopyTo(fileStream);
            }
        }
    }
    return new FileResult
    {
        FileNames = streamProvider.Contents.Select(entry => entry.Headers.ContentDisposition.FileName?.Trim('"') ?? ""),
        Names = streamProvider.Contents.Select(entry => entry.Headers.ContentDisposition.Name?.Trim('"') ?? ""),
        ContentTypes = streamProvider.Contents.Select(entry => entry.Headers.ContentType?.MediaType ?? ""),
        CreatedTimestamp = DateTime.UtcNow,
        UpdatedTimestamp = DateTime.UtcNow,
    };
}

Please note that upload to the memory of server will consume the memory resource. It is not a good solution for large files or with a lot of HTTP traffic.

Test

Create a simple html page

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>File Upload</title>
</head>
<body>
    <div>
        <form enctype="multipart/form-data" method="post" action="http://localhost:45505/api/files" novalidate="novalidate">         
            <fieldset>
                <legend>Upload Form</legend>
                <ol>
                    <li>
                        <label>Description </label>
                        <input type="text" name="description" id="description">
                    </li>
                    <li>
                        <label>Upload </label>
                        <input type="file" name="file" id="fileInput" multiple>                  
                    </li>
                    <li>
                        <input type="submit" value="Upload">
                    </li>
                </ol>
            </fieldset>
        </form>
    </div>
</body>
</html>

Upload a file

Upload multiple files

References

https://damienbod.com/2014/03/28/web-api-file-upload-single-or-multiple-files/

http://www.intstrings.com/ramivemula/articles/file-upload-using-multipartformdatastreamprovider-in-asp-net-webapi/