16

I have web api project.

I need to post there json data with file as encoded base64 string (up to 200 mb).

If i send data up to about 10 mb, then next method normally get properly filled model ImportMultipleFileModel.

[HttpPost]
    public async Task<HttpResponseMessage> ImportMultipleFiles(ImportMultipleFileModel importMultipleFileModel)
    { 
        var response = ImportFiles(importFileModel);
        return response;
    }

If i send more, then model is null.

Why?

So i change method signature to:

    [HttpPost]
        public async Task<HttpResponseMessage> ImportMultipleFiles()
        {
            ImportMultipleFileModel importMultipleFileModel = null;
            var requestData = await Request.Content.ReadAsStringAsync();
            try
            {
                JsonConvert.
                importMultipleFileModel = JsonConvert.DeserializeObject<ImportMultipleFileModel>(requestData);
            }catch(Exception e)
            { }
}

And for encoded 30 mb file i normally get requestData as json string. For 60 mb i get empty string. Why?

Next i change method to

    [HttpPost]
        public async Task<HttpResponseMessage> ImportMultipleFiles()
        {
            ImportMultipleFileModel importMultipleFileModel = null;
            var requestData = Request.Content.ReadAsStringAsync().Result;
            try
            {
                importMultipleFileModel = JsonConvert.DeserializeObject<ImportMultipleFileModel>(requestData);
            }catch(Exception e)
            { }
}

And deserialization failed because of OutOfMemoryException.

Why?

UPD: maxRequestLength, maxAllowedContentLength set to 2147483647

vitm
  • 473
  • 1
  • 3
  • 12
  • It's trying to serialise 60mb of string into a construct which doesn't allow for this. You wouldn't want to hold 60mb of memory per request any way. This is why you either use streams, or you split out the requests – Callum Linington Jul 25 '16 at 08:41

1 Answers1

19

Try setting the maxRequestLength.

<httpRuntime targetFramework="4.5" maxRequestLength="65536" />

Or maxAllowedContentLength (I always get confused which one's which).

<security>
  <requestFiltering>
    <requestLimits maxAllowedContentLength="52428800" />
  </requestFiltering>
</security>

Also, I would reconsider posting data this way. Read this article form MSDN, it's mainly for WCF, but I think the content is mostly valid.

The strategy to deal with large payloads is streaming.

Side note for your last example; you should not (or perhaps rarely) use .Result when you can use await. Stephen Cleary wrote a good answer on that here.

user247702
  • 23,641
  • 15
  • 110
  • 157
smoksnes
  • 10,509
  • 4
  • 49
  • 74
  • It's already done. Set to 2147483647. Sorry, i didn.t point it. – vitm Jul 25 '16 at 09:11
  • The maxRequestLength setting fixed the issue for me – Mark Wagoner Apr 03 '18 at 12:41
  • 1
    I have an ASP.Net WebForm project which provides Web API as well. I used `maxAlloweContentLength="20971520"` 20MB and it works fine for the web pages while the API request supports only smaller files (up to 13MB). – Hamid Mayeli Nov 22 '18 at 14:21