Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebAPI error reading MIME multipart body part

My team recently refactored a Web API service to move some of the repetitive code into static methods. One method is related to extracting an uploaded file from the request. The method works in unit testing, but under load, is throwing exceptions. Part of the code was found in an SO post, but I'm concerned that, overall, we're not using it correctly. Here's the code:

internal static string ExtractFile(HttpRequestMessage request)
{
    if (request.Content.IsMimeMultipartContent())
    {
        string uploadRoot = ServiceHelper.GetUploadDirectoryPath();

        var provider = new MultipartFormDataStreamProvider(uploadRoot);

        try
        {
            Task.Factory
            .StartNew(() => provider = request.Content.ReadAsMultipartAsync(provider).Result,
                CancellationToken.None,
                TaskCreationOptions.LongRunning, // guarantees separate thread
                TaskScheduler.Default)
            .Wait();
        }
        catch(System.AggregateException ae)
        {
            if(log.IsErrorEnabled)
            {
                foreach(var ex in ae.InnerExceptions)
                {
                    log.Error("ReadAsMultipartAsync task error.", ex);
                }
            }

            var errorResponse = request.CreateErrorResponse(HttpStatusCode.InternalServerError, "An error occurred while extracting the uploaded file from the request.");
            throw new HttpResponseException(errorResponse);
        }

        var fileData = provider.FileData.First();

        var localName = fileData.LocalFileName;
        var content = File.ReadAllText(localName);

        if (log.IsDebugEnabled)
        {
            var embeddedName = fileData.Headers.ContentDisposition.FileName;
            log.DebugFormat("File {0} was successfully uploaded as '{1}'.", embeddedName, localName);
        }

        return content;
    }
    else
    {
        log.Error("Invalid request received. Request must be in a multipart/form-data request.");

        var errorResponse = request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Request must be a multipart/form-data request and contain one file.");
        throw new HttpResponseException(errorResponse);
    }
}

Walking thru the logs, I see errors like these:

System.IO.IOException: Error reading MIME multipart body part. ---> System.IO.IOException ---> System.Net.HttpListenerException: The I/O operation has been aborted because of either a thread exit or an application request

HttpListenerRequest disposed

System.IO.IOException: Error reading MIME multipart body part. ---> System.IO.IOException ---> System.Net.HttpListenerException: An operation was attempted on a nonexistent network connection

This web service is running as a self-hosted OWIN Windows service. The file uploads are small (3k to 4k).

I can't recreate the issue with a single upload. The client that is talking to the service uses tasks to post files, but it doesn't usually run more than 4 or 5 tasks concurrently. My team and I are relatively new to .NET tasks. One of the developers is wondering if the TaskCreationOptions.LongRunning parameter is actually hurting more than it helps. Any suggestions?

Update:

I tried switching out the Task.Factory code with this:

var task = Task.Run(async () => await request.Content.ReadAsMultipartAsync(provider));
task.Wait();
provider = task.Result;

I'm still having some issues, but this seems to work better. Not sure why, though.

like image 984
Doug Dawson Avatar asked Aug 17 '16 18:08

Doug Dawson


1 Answers

I had the same issue, it was resolved by adding following code in web.config

<system.web>
    <httpRuntime maxRequestLength="30000000" />
</system.web>

<system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="30000000" />
      </requestFiltering>
    </security>
</system.webServer>

Source: http://stackoverflow.com/questions/20942636/webapi-cannot-parse-multipart-form-data-post

like image 88
Khateeb321 Avatar answered Sep 30 '22 03:09

Khateeb321