Reading content to the memory from the multi-part file upload

10,366

The solution was actually quite simple. MultipartFormDataStreamProvider is not required when we are not dealing with files. This works quite smoothly on my case.

[WebInvoke(Method = "POST", UriTemplate = "{importFile}")]
public HttpResponseMessage Upload(
    string importFile, HttpRequestMessage request)
{
    if (!request.Content.IsMimeMultipartContent())
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);

    // Read the MIME multipart content 
    var task = request.Content.ReadAsMultipartAsync();            
    task.Wait();

    IEnumerable<HttpContent> bodyparts = task.Result;
    string submitter;
    if (!bodyparts.TryGetFormFieldValue("submitter", out submitter))
        submitter = "unknown";

    var parser = this.parserFactoryFactory.CreateParser();
    foreach (var part in bodyparts)
    {
        using (var stream = part.ContentReadStream)
        {
            using (var streamReader = new StreamReader(stream))
            {
                string content = streamReader.ReadToEnd();
                var results = parser.Parse(content);
                if (results.IsValid)
                    // do something
            }
        }
    }
    var message = new HttpResponseMessage(HttpStatusCode.Accepted);
    return message;
}  
Share:
10,366
Tx3
Author by

Tx3

Independent web developer focusing on architecture design, performance &amp; maintainability. Over 10 years of experience on cutting-edge web development.

Updated on September 25, 2022

Comments

  • Tx3
    Tx3 over 1 year

    I have a problem reading uploaded XML file to the string instead of file.

    My problem is that when I try to access the stream (var stream = part.ContentReadStream) then it's closed. I have feeling that it is accessing closed file stream. Am I using MultipartFormDataStreamProvider incorrectly? File size is only few kilobytes, so that should not be a problem.

        [WebInvoke(Method = "POST", UriTemplate = "{importFile}")]
        public HttpResponseMessage Upload(string importFile, HttpRequestMessage request)
        {
            if (!request.Content.IsMimeMultipartContent())
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }
    
            // Create a stream provider for setting up output streams
            MultipartFormDataStreamProvider streamProvider = new MultipartFormDataStreamProvider();
    
            // Read the MIME multipart content using the stream provider we just created.
            var task = request.Content.ReadAsMultipartAsync(streamProvider);
            task.Wait();
            IEnumerable<HttpContent> bodyparts = task.Result;
            string submitter;
            if (!bodyparts.TryGetFormFieldValue("submitter", out submitter))
            {
                submitter = "unknown";
            }
    
            // Get list of local file names from stream provider
            IDictionary<string, string> bodyPartFileNames = streamProvider.BodyPartFileNames;
    
    
            var parser = this.parserFactoryFactory.CreateParser();
            foreach (var part in bodyparts)
            {
                using (var stream = part.ContentReadStream)
                {
                    using (var streamReader = new StreamReader(stream))
                    {
                        string content = streamReader.ReadToEnd();
                        var results = parser.Parse(content);
                    }
                }
            }
            return new HttpResponseMessage(HttpStatusCode.Accepted);
        }  
    

    This is my post

    <h3>Data import test</h3>
    
    <form action="/api/data/Upload" enctype="multipart/form-data" method="POST">
        <input type="file" name="importFile"/>
        <input type="submit" value="Upload"/>
    </form>