Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File Name from HttpRequestMessage Content

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. lets 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?

like image 286
gosua Avatar asked Jan 14 '23 04:01

gosua


1 Answers

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;

    }
}
like image 179
Filip W Avatar answered Jan 22 '23 20:01

Filip W