File Name from HttpRequestMessage Content

asp.net-mvc, asp.net-web-api, file-upload, post, rest

Solution

If you upload file to Web API and you want to get access to file data (`Content-Disposition`) you should upload the file as MIME multipart (`multipart/form-data`).

Here I showed some examples on how to upload from HTML form, Javascript and from .NET.

You can then do something like this, this example checks for pdf/doc files only:

public async Task<HttpResponseMessage> Post()
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable,
                                                                   "This request is not properly formatted - not multipart."));
        }

        var provider = new RestrictiveMultipartMemoryStreamProvider();

        //READ CONTENTS OF REQUEST TO MEMORY WITHOUT FLUSHING TO DISK
        await Request.Content.ReadAsMultipartAsync(provider);

        foreach (HttpContent ctnt in provider.Contents)
        {
            //now read individual part into STREAM
            var stream = await ctnt.ReadAsStreamAsync();

            if (stream.Length != 0)
            {
                using (var ms = new MemoryStream())
                {
                    //do something with the file memorystream
                }
            }
        }
        return Request.CreateResponse(HttpStatusCode.OK);
    }
}

public class RestrictiveMultipartMemoryStreamProvider : MultipartMemoryStreamProvider
{
    public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
    {
        var extensions = new[] {"pdf", "doc"};
        var filename = headers.ContentDisposition.FileName.Replace("\"", string.Empty);

        if (filename.IndexOf('.') < 0)
            return Stream.Null;

        var extension = filename.Split('.').Last();

        return extensions.Any(i => i.Equals(extension, StringComparison.InvariantCultureIgnoreCase))
                   ? base.GetStream(parent, headers)
                   : Stream.Null;

    }
}

Problem

I implemented a POST Rest service to upload files to my server. The problem I have right now is that I want to restrict the uploaded files by its type. Let's say for example I only want to allow pdf files to be uploaded. What I tried to do was: ``` Task<Stream> task = this.Request.Content.ReadAsStreamAsync(); task.Wait(); FileStream requestStream = (FileStream)task.Result; ``` but unfortunately its not possible to cast the Stream to a FileStream and access the type via requestStream.Name. Is there an easy way (except writing the stream to the disk and check then the type) to get the filetype?

Original source