Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the stream for a Multipart file in webapi upload?

I need to upload a file using Stream (Azure Blobstorage), and just cannot find out how to get the stream from the object itself. See code below.

I'm new to the WebAPI and have used some examples. I'm getting the files and filedata, but it's not correct type for my methods to upload it. Therefore, I need to get or convert it into a normal Stream, which seems a bit hard at the moment :)

I know I need to use ReadAsStreamAsync().Result in some way, but it crashes in the foreach loop since I'm getting two provider.Contents (first one seems right, second one does not).

 [System.Web.Http.HttpPost]
    public async Task<HttpResponseMessage> Upload()
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            this.Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
        }

        var provider = GetMultipartProvider();
        var result = await Request.Content.ReadAsMultipartAsync(provider);

        // On upload, files are given a generic name like "BodyPart_26d6abe1-3ae1-416a-9429-b35f15e6e5d5"
        // so this is how you can get the original file name
        var originalFileName = GetDeserializedFileName(result.FileData.First());

        // uploadedFileInfo object will give you some additional stuff like file length,
        // creation time, directory name, a few filesystem methods etc..
        var uploadedFileInfo = new FileInfo(result.FileData.First().LocalFileName);



        // Remove this line as well as GetFormData method if you're not
        // sending any form data with your upload request
        var fileUploadObj = GetFormData<UploadDataModel>(result);

        Stream filestream = null;

        using (Stream stream = new MemoryStream())
        {
            foreach (HttpContent content in provider.Contents)
            {
                BinaryFormatter bFormatter = new BinaryFormatter();
                bFormatter.Serialize(stream, content.ReadAsStreamAsync().Result);
                stream.Position = 0;
                filestream = stream;
            }
        }

        var storage = new StorageServices();
        storage.UploadBlob(filestream, originalFileName);**strong text**



private MultipartFormDataStreamProvider GetMultipartProvider()
    {
        var uploadFolder = "~/App_Data/Tmp/FileUploads"; // you could put this to web.config
        var root = HttpContext.Current.Server.MapPath(uploadFolder);
        Directory.CreateDirectory(root);
        return new MultipartFormDataStreamProvider(root);
    }
like image 728
Terje Nygård Avatar asked Jul 17 '14 14:07

Terje Nygård


2 Answers

This is identical to a dilemma I had a few months ago (capturing the upload stream before the MultipartStreamProvider took over and auto-magically saved the stream to a file). The recommendation was to inherit that class and override the methods ... but that didn't work in my case. :( (I wanted the functionality of both the MultipartFileStreamProvider and MultipartFormDataStreamProvider rolled into one MultipartStreamProvider, without the autosave part).

This might help; here's one written by one of the Web API developers, and this from the same developer.

like image 67
Sameer Singh Avatar answered Sep 23 '22 10:09

Sameer Singh


Hi just wanted to post my answer so if anybody encounters the same issue they can find a solution here itself.

here

 MultipartMemoryStreamProvider stream = await this.Request.Content.ReadAsMultipartAsync();
            foreach (var st in stream.Contents)
            {
                var fileBytes = await st.ReadAsByteArrayAsync();
                string base64 = Convert.ToBase64String(fileBytes);
                var contentHeader = st.Headers;
                string filename = contentHeader.ContentDisposition.FileName.Replace("\"", "");
                string filetype = contentHeader.ContentType.MediaType;
            }    

I used MultipartMemoryStreamProvider and got all the details like filename and filetype from the header of content. Hope this helps someone.

like image 28
Abhay Garg Avatar answered Sep 23 '22 10:09

Abhay Garg