5

I'm trying to get the blueimp jQuery-File-Upload component working in my MVC application.

Here's my code so far.

JavaScript:

$('#fileupload').fileupload({
    url: '@Url.Action("AddAttachment", "File")',
    dataType: 'json',
    progressall: function (e, data) {
        var progress = parseInt(data.loaded / data.total * 100, 10);
        console.log(progress);
    },
    add: function(e, data) {
        data.submit();
    },
    done: function (e, data) {
        $.each(data.result.files, function (index, file) {
            $('<p/>').text(file.name).appendTo(document.body);
        });
    }
});

Controller:

[HttpPost]
public JsonResult AddAttachment()
{
    var files = new List<FileAttachmentFileModel>();

    try
    {
        if (Request.Files.Count > 0)
        {
            using (var dbContext = new vegaEntities())
            using (var transaction = dbContext.Database.BeginTransaction())
            {
                for (int i = 0; i < Request.Files.Count; i++)
                {
                    HttpPostedFileBase file = Request.Files[i];

                    if (file.ContentLength > 0)
                    {
                        FileAttachment fileAttachment = new FileAttachment
                        {
                            Id = Guid.NewGuid(),
                            FileName = file.FileName,
                            ContentType = file.ContentType,
                            DateAdded = DateTime.UtcNow
                        };
                        // Load content
                        fileAttachment.Content = new byte[file.ContentLength];
                        file.InputStream.Read(fileAttachment.Content, 0, file.ContentLength);
                        // Add to database
                        dbContext.FileAttachments.Add(fileAttachment);
                        // Add to results
                        files.Add(new FileAttachmentFileModel
                        {
                            id = fileAttachment.Id.ToString(),
                            name = file.FileName,
                            size = file.ContentLength.FormatAsFileSize(),
                            //action = FileAttachmentFileModel.AddAction
                        });
                    }
                }
                dbContext.SaveChanges();
                transaction.Commit();
            }
        }
    }
    catch (Exception ex)
    {
        // TODO:
        return Json(new { message = ex.Message });
    }
    return Json(new { files = files });
}

This code is working with smaller files. My C# method gets called, the file is retrieved, and the progressall handler is called showing 100%.

The problem is when I attempt to upload a large file (where the progressall handler gets called more than once). In that case, the handler gets called with incrementing progress values up to 100%, as expected. But my C# method never gets called and the browser reports the following error.

POST http://localhost:1290/File/AddAttachment 404 (Not Found)

I'm confused by this error because the C# method is the same in both cases. Why is it found in one and not found in the other. I assume the issue is that my controller method is expecting a complete file and that I must instead write code to handle the upload in chunks. Is this right? Can anyone point me to documentation on how to write an upload handler using C#/MVC?

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
  • Which version of MVC and .NET are you using? – Master Yoda Nov 07 '17 at 22:25
  • @MasterYoda: Right now, I'm using the ones that came with Visual Studio 2015, but could upgrade if there was a reason to. Would that make a difference? – Jonathan Wood Nov 07 '17 at 22:26
  • probably not a massive difference, i reckon you are probably using .net 4.5 - 4.6 based on your version of VS. I have done this before using asp.net by serializing the entire file using a **Stream, BinaryReader and Byte array**. Check out my question here: https://stackoverflow.com/questions/17233884/files-do-not-download-in-correct-format. I also did something similar with multiple file types using a similar file upload control except i was reading the file row by row and exporting each row to a mapping in the DB. Give me a little time and i will see if i can dig that out :) – Master Yoda Nov 07 '17 at 22:32
  • @MasterYoda: It seems like you are doing something quite different. For example, you appear to be using WebForms instead of MVC. Second, you don't appear go be using AJAX that I can tell. And perhaps the biggest difference is that you don't appear to be using the jQuery file upload component that I'm trying to get working. – Jonathan Wood Nov 07 '17 at 22:35
  • Yes thats true, but im not suggesting that you copy the entire example line by line, im just suggesting that you serialize your file into a stream and go from there. You cant use my example anyway as it uses a Telerik AJAX control to upload the document. I dont think there is an issue with the file upload control you are using, i think its probably more to do with how its handled server side – Master Yoda Nov 07 '17 at 22:37
  • Also, have you seen this link? its an example of using blueImp with MVC3 so may be of use to you: https://github.com/maxpavlov/jQuery-File-Upload.MVC3 – Master Yoda Nov 07 '17 at 22:43
  • @MasterYoda: Yes, I have. But in addition to being somewhat outdated, his uploader server-side handling code says not to use that for larger files. – Jonathan Wood Nov 07 '17 at 22:48
  • Where do you set `httpmethod` to send file (in javascript)? I think this fires the error. – Amirhossein Mehrvarzi Nov 11 '17 at 08:23
  • @AmirhosseinMehrvarzi: I have a `
    ` tag in the markup that specifies it should use POST. Also, you can see from the error that it is using POST. I'm not sure why you say you think this fires the error. Not enough detail there to go on.
    – Jonathan Wood Nov 12 '17 at 19:36

2 Answers2

3

Dang it! It was an issue with the maximum file size being exceeded. I know this. I've dealt with it before. But I got confused by the 404 error! D'oh!

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
  • 2
    So why it returns 404 and not something more meaningful? – Evk Nov 10 '17 at 07:35
  • 1
    Yeah, that's what I wanted to know. – Jonathan Wood Nov 10 '17 at 13:00
  • 3
    Here is similar question: https://stackoverflow.com/q/4731295/5311735. There you can see IIS returns 404.13 when request size exceeds maxAllowedContentLength. And if you list answers quite a bit you can find one that describes how to redirect this specific error (404 with subcode 13) to your mvc controller which can provide more meaningful description. – Evk Nov 10 '17 at 13:06
1

In fact, there is a trigger that depends on the incorrect opening of the high file which is not downloaded on its base.

The 404 error depends on the IIS security protocol

If you are going to examine the details of Request and Response, you can see it yourself

I do not recommend resolving it by the IIS administrator.

If you will set it at the application level

an example in web.config;

<System.webServer>
    <Security>
      <RequestFiltering>
        <requestLimits maxAllowedContentLength = "30000000" />
      </ requestFiltering>
    </ security>
  </system.webServer>
mdora7
  • 41
  • 1
  • 5
  • I don't understand what you're saying. What do you mean by a trigger? – Jonathan Wood Nov 17 '17 at 00:56
  • @JonathanWood the file is not downloaded in its actual size, then this file is trying to open.IIS is putting the security protocol into effect in this case – mdora7 Nov 17 '17 at 08:03