Coder Perfect

Accepting a File POST:


To create a rest service, I’m using the mvc 4 webapi beta. I need to be able to receive images/files that have been POSTed from client applications. Is it possible to do this with the webapi? The action I’m now using is shown below. Is there a good example of how this should work?

public string ProfileImagePost(HttpPostedFile profileImage)
    string[] extensions = { ".jpg", ".jpeg", ".gif", ".bmp", ".png" };
    if (!extensions.Any(x => x.Equals(Path.GetExtension(profileImage.FileName.ToLower()), StringComparison.OrdinalIgnoreCase)))
        throw new HttpResponseException("Invalid file type.", HttpStatusCode.BadRequest);

    // Other code goes here

    return "/path/to/image.png";

Asked by Phil

Solution #1

Many of you appear to want to save files on the server, which surprises me. The following is a solution for remembering everything:

public async Task<IHttpActionResult> Upload()
    if (!Request.Content.IsMimeMultipartContent())
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); 

    var provider = new MultipartMemoryStreamProvider();
    await Request.Content.ReadAsMultipartAsync(provider);
    foreach (var file in provider.Contents)
        var filename = file.Headers.ContentDisposition.FileName.Trim('\"');
        var buffer = await file.ReadAsByteArrayAsync();
        //Do whatever you want with filename and its binary data.

    return Ok();

Answered by Gleno

Solution #2, although I believe the article oversimplifies things.


public Task<HttpResponseMessage> PostFile() 
    HttpRequestMessage request = this.Request; 
    if (!request.Content.IsMimeMultipartContent()) 
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); 

    string root = System.Web.HttpContext.Current.Server.MapPath("~/App_Data/uploads"); 
    var provider = new MultipartFormDataStreamProvider(root); 

    var task = request.Content.ReadAsMultipartAsync(provider). 
        ContinueWith<HttpResponseMessage>(o => 

        string file1 = provider.BodyPartFileNames.First().Value;
        // this is the file name on the server where the file was saved 

        return new HttpResponseMessage() 
            Content = new StringContent("File uploaded.") 
    return task; 

Answered by Mike Wasson

Solution #3

See the code below, which is based from this post and shows the most basic sample code I could locate. It supports both file and memory uploads (which are faster).

public HttpResponseMessage Post()
    var httpRequest = HttpContext.Current.Request;
    if (httpRequest.Files.Count < 1)
        return Request.CreateResponse(HttpStatusCode.BadRequest);

    foreach(string file in httpRequest.Files)
        var postedFile = httpRequest.Files[file];
        var filePath = HttpContext.Current.Server.MapPath("~/" + postedFile.FileName);
        // NOTE: To store in memory use postedFile.InputStream

    return Request.CreateResponse(HttpStatusCode.Created);

Answered by Brent Matzelle

Solution #4

The ASP.NET Core approach is now available:

public async Task<IActionResult> Post(List<IFormFile> files)
    long size = files.Sum(f => f.Length);

    // full path to file in temp location
    var filePath = Path.GetTempFileName();

    foreach (var formFile in files)
        if (formFile.Length > 0)
            using (var stream = new FileStream(filePath, FileMode.Create))
                await formFile.CopyToAsync(stream);

    // process uploaded files
    // Don't rely on or trust the FileName property without validation.

    return Ok(new { count = files.Count, size, filePath});

Answered by Matt Frear

Solution #5

Here’s a quick and dirty approach for reading the contents of an uploaded file from the HTTP body and writing them to a file. For the file upload, I provided a “bare bones” HTML/JS snippet.

Web API Method:

public string MyFileUpload()
    var request = HttpContext.Current.Request;
    var filePath = "C:\\temp\\" + request.Headers["filename"];
    using (var fs = new System.IO.FileStream(filePath, System.IO.FileMode.Create))
    return "uploaded";

HTML File Upload:

    <input type="file" id="myfile"/>  
    <input type="button" onclick="uploadFile();" value="Upload" />
<script type="text/javascript">
    function uploadFile() {        
        var xhr = new XMLHttpRequest();                 
        var file = document.getElementById('myfile').files[0];"POST", "api/myfileupload");

Answered by James Lawruk

Post is based on