14

I've been trying to get this to work, but to no avail.

What I am trying to do, is to upload a set of FormData images and attachments using JQuery AJAX.

I keep getting the error: "Multipart body length limit 16384 exceeded"

I found another similar question here on SO: Multipart body length limit exceeded exception

If anyone here can help me out or point me in a direction, that would be greatly appreciated. It's almost midnight on my side, and I'm about to give up :(.

I am using ASP.NET Core 1.1.

Here is my javascript:

let data = new FormData();
    data.enctype = "multipart/form-data";
    let file = $("#imgItem_image-upload-file")[0].files[0];

    data.append("image|" + file.name, file); //Works fine if alone.

    //Does not work, causes error on server side.
    for (var i = 0; i < objItem.Attachments[0].length; i++) {
        let attFile = objItem.Attachments[0][i].File;
        console.log(attFile);
        data.append("attachment|" + attFile.name, attFile);
    }

    data.append("Category", objItem.Category);
    data.append("NewCategory", objItem.NewCategory);
    data.append("Name", objItem.Name);
    data.append("IdentificationType", objItem.IdentificationType);
    data.append("SerialNumber", objItem.SerialNumber);
    data.append("IMEI", objItem.IMEI);
    data.append("EngineNumber", objItem.EngineNumber);
    data.append("MASNumber", objItem.MASNumber);
    data.append("NumberPlate", objItem.NumberPlate);
    data.append("VINNumber", objItem.VINNumber);
    data.append("Description", objItem.Description);
    $.ajax({
        url: "http://localhost:7001/api/AddPersonalItem",
        type: "POST",
        data: data,
        //dataType: "json",
        //headers: { 'Content-Type': false },
        //contentType: false,
        contentType: false, //'multipart/form-data'
        processData: false,
        // headers: { 
        //     'Accept': 'application/json',
        //     'Content-Type': 'application/json' 
        // },
        success: function (response) {

        },
        error: function(jqXHR, textStatus, errorThrown) {
            console.log(textStatus, errorThrown);
        }
    });

I also added this to my Startup.js file:

    public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddMvc();

        //Multipart
        services.Configure<FormOptions>(x =>
        {
            x.MultipartBodyLengthLimit = 60000000;
        });
    }

And here is my API Controller's code:

        public ServiceCallResponse AddPersonalItem()
        {
            ItemObject io = new ItemObject();
            io.Attachments = new List<Attachment>();
            io.Image = new Image();

            //Get files.
            foreach (IFormFile file in Request.Form.Files)
            {
                //The file name also states what type of object this is.
                string type = file.Name.Split('|')[0];
                string name = file.Name.Split('|')[1];

                StreamReader reader = new StreamReader(file.OpenReadStream());
                byte[] bytes = Encoding.Unicode.GetBytes(reader.ReadToEnd());
                string base64 = Convert.ToBase64String(bytes);

                switch (type.ToLower().Trim())
                {
                    case "attachment":
                        Attachment a = new Attachment();
                        a.Name = name;
                        a.Base64 = base64;

                        io.Attachments.Add(a);
                        break;
                    case "image":
                        io.Image.Name = name;
                        io.Image.Base64 = base64;
                        break;
                }
            }
        }

Even after increasing the multipart body length, i am still getting the exact same error.

The error occurs on:

foreach (IFormFile file in Request.Form.Files)

If I am not clear enough n this, please ask and I'll try to ellaborate! :)

Community
  • 1
  • 1
Fred
  • 2,402
  • 4
  • 31
  • 58
  • 1
    I would really like to use .NET Core on this, but I am starting to think that I need to switch to WCF for my service... after 22 days and counting... – Fred Feb 23 '17 at 08:04
  • https://github.com/aspnet/Mvc/issues/5128 – Jason Rowe Mar 13 '17 at 18:25
  • 1
    So I eventually ended up dropping .NET Core and doing this in ASP.NET API 2. I still have not figured out how to allow .NET Core to allow files bigger than that default. All the links I tried just simply does not work. API 2 works 100% fine - I'll now just need a windows hosting environment... – Fred Mar 23 '17 at 09:12
  • Is there any `FormOptions` equivalent for `.NET Standard` because my solutino is in `.NET Standard` and i have the same error regarding a `html` form. – Bercovici Adrian Mar 13 '19 at 07:51

4 Answers4

14

In my case the solution was to increase MemoryBufferThreshold.

services.Configure<FormOptions>(options =>
{
    options.MemoryBufferThreshold = Int32.MaxValue;
});
Hav
  • 870
  • 8
  • 17
  • Oldie, but a goodie. Thank you! Increasing MultipartBodyLengthLimit was not sufficient, the memory buffer threshold had to be increased as well. The error was kind of misleading in that way, because it was saying "multipart body length limit '16384' exceeded" either way. – Brett May 21 '20 at 23:34
5

I got the exception and I found that my client had a incorrect HTTP header "content-type". Using curl with the incorrect input type curl tried to send the entire file in the POST Body as text, not a great move :-)

Example with curl: This failed:

curl --request POST \
  --url https://stuff.net/api/storage \
  --header 'authorization: bearer MY_ACCESS_TOKEN' \
  --header 'cache-control: no-cache' \
  --header 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
  --form MyfileName=b72871d79c81 \
  --form file=@nature-sky-twilight.jpg \
  --form MyfileId=9401c94db46c

This worked:

curl --request POST \
  --url https://stuff.net/api/storage \
  --header 'authorization: bearer MY_ACCESS_TOKEN' \
  --header 'cache-control: no-cache' \
  --form MyfileName=b72871d79c81 \
  --form file=@nature-sky-twilight.jpg \
  --form MyfileId=9401c94db46c
janCoffee
  • 375
  • 3
  • 5
2

You need to increase the value length limit as well. Default is like 4MB.

              services.Configure<FormOptions>(options =>
                {
                    options.ValueCountLimit = 10; //default 1024
                    options.ValueLengthLimit = int.MaxValue; //not recommended value
                    options.MultipartBodyLengthLimit = long.MaxValue; //not recommended value
                });
dynamiclynk
  • 2,275
  • 27
  • 31
  • 1
    Is there any `FormOptions` equivalent for `.NET Standard`? I am running into the same problem. – Bercovici Adrian Mar 13 '19 at 07:50
  • What would be recommended values for `ValueLengthLimit` and `MultipartBodyLengthLimit`? – Will Marcouiller Apr 09 '20 at 13:52
  • 1
    @WillMarcouiller that would depend on your expected upload payload or you can leave it as the MaxValues if you have some other content restrictions server side it's just not recommended out-of the box unless you have some restrictions to prevent people from misusing it by uploading huge files which could 1. cost you money for storage possibly 2. Depending on the destination it could end up filling up your disks with obscure data. – dynamiclynk Apr 09 '20 at 15:03
  • 1
    @dynamiclynk I better understand stakes, thx. I set mine to `60000000`, as OP set it, and I can now upload my pictures fine. :) – Will Marcouiller Apr 09 '20 at 15:16
0

In my case, Content-Type in postman need to be checked.