简体   繁体   中英

WebAPI using PostAsync throws exception only when filesize is large

I am trying to send a file to a WebAPI controller that does some processing with the file on a server. Everything seems to work well until I tried files that are large than 2mb... files large than this seem to be throwing an odd exception.

Here is the snippet:

       var progress = new ProgressMessageHandler();
        progress.HttpSendProgress += ProgressEventHandler;
        HttpClient client = HttpClientFactory.Create(progress);
        client.Timeout = TimeSpan.FromMinutes(20);
try  
                {
                    using (
                        var fileStream = new FileStream(file, FileMode.Open,      FileAccess.Read, FileShare.Read, 1024,
                        useAsync: true))
                {
                    var content = new StreamContent(fileStream, 1024);
                    var address = new Uri(string.Format("{0}api/File/Upload?submittalId={1}&fileName={2}&documentTypeId={3}", FileServiceUri, tabTag.submittalId, Path.GetFileName(file), documentTypeId));
                    client.MaxResponseContentBufferSize = 2147483647;
                    var response = await client.PostAsync(address, content);
                    var result = response.Content.ReadAsAsync<object>();
                    if (!response.IsSuccessStatusCode)
                        continue;
                }

The exception is thrown on the line:

var response = await client.PostAsync(address, content);

and is:

No MediaTypeFormatter is available to read an object of type 'Object' from content with media type 'text/html'

It's not even hitting the breakpoint at the beginning of my service controller so I didnt include that code(although I can if thats potentially an issue). As I said above, this ONLY happens with files > 2mb -- small files work just fine(thank god so I have something to show for a demo ^^).

Anyhelp with this would be greatly appreciated.

Cory's observation is right that Web API doesn't have a in-built formatter to either serialize or deserialize text/html content. My guess is that you are most probably getting an error response in html. If its indeed that, you can do the following:

When uploading files to a IIS hosted Web API application, you need to take care of the following stuff.

You need to look for the following 2 settings in Web.config to increase the upload size:

NOTE(maxRequestLength="size in Kilo bytes") :

<system.web> <httpRuntime targetFramework="4.5" maxQueryStringLength="" maxRequestLength="" maxUrlLength="" />

NOTE(maxAllowedContentLength is in bytes) :

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

Also note that the default buffer policy of Web API in IIS hosted scenarios is buffered , so if you are uploading huge files, your request would be consuming lot of memory. To prevent that you can change the policy like the following:

config.Services.Replace(typeof(IHostBufferPolicySelector), new CustomBufferPolicySelector());  

//---------------  

public class CustomBufferPolicySelector : WebHostBufferPolicySelector
{
    public override bool UseBufferedInputStream(object hostContext)
    {
        return false;
    }
}

The response is coming back with a text/html Content-Type, and ReadAsAsync<object>() doesn't know how to deserialize text/html into an object .

Likely, your web app is configured to only accept files up to a certain size and is returning an error with a friendly HTML message. You should be checking the response code before trying to deserialize the content:

var response = await client.PostAsync(address, content);
response.EnsureSuccessStatusCode();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM