2

Just a quick question,

I have done a lot of research on this already but I have a different approach.

My problem: I have a file uploader that works in all browsers using asp.net with VB. The issue is that our system only allows files to be uploaded that are no bigger than 1mb. Now, using a check on the back-end, It will tell the user if the file is too big, and that they must upload a smaller file. However, the weird problem is that it will catch a file that is 2-3mb over the limit. Not if a file is 20mb for example. If upload it, I will get a nasty debug error saying the max file size has been requested.

What I wanted to do was a quick check on the front end to preven it from even being sent to the backend.

I used:

$(function(){
    $('#File1').bind('change', function() {
          alert(this.files[0].size);
        });
});

To check the file size. It works in chrome and firefox. But not IE. I heard using ActiveX could work if the user allows it in the privacy setting.

I could use browser detection to say "hey, if IE do activeX else do the jQuery" But I am wondering if there is a more reliable method than ActiveX?

Zeddy
  • 2,079
  • 1
  • 15
  • 23
Christian4423
  • 1,746
  • 2
  • 15
  • 25
  • what is `this.files`? need moar code. Post the html and any other relevant javascript. Also post what "not working" means in IE. Does it not run at all? Does it throw an error? What's the message? – basher May 27 '15 at 21:43
  • Your tags for the question are VB.Net .... This is not VB Code! – Zeddy May 27 '15 at 22:48

1 Answers1

5

Your problem is due to the fact that all IE versions prior to 10 have no support for the HTML5 File API. So, considering that this is your HTMLInputElement, the following won't work:

this.files[0].size;

The reason is that HTMLInputElement.FileList does not exist since the lack of File API support, but you could get the file's name with HTMLInputElement.value. But that's not what you want. You want to get the file's size. Once again, because of the lack of the File API support, IE < 10 doesn't supply the file size information. So, the only way to check the file size for these lesser versions, is to use ActiveX, even if nobody likes doing so.

First solution (client side - jQuery)

You proposed:

I could use browser detection to say "hey, if IE do activeX else do the jQuery"

If you want to do so, you could have something like that:

$(function(){
    $('#File1').bind('change', function() {
        var maxFileSize = 1024000; // 1MB -> 1000 * 1024
        var fileSize;

        // If current browser is IE < 10, use ActiveX
        if (isIE() && isIE() < 10) {
            var filePath = this.value;
            if (filePath != '') {
                var AxFSObj = new ActiveXObject("Scripting.FileSystemObject");
                var AxFSObjFile = AxFSObj.getFile(filePath);
                fileSize = AxFSObjFile.size;
            }
        } else {
            // IE >= 10 or not IE

            if (this.value != '') {
                fileSize = this.files[0].size;
            }
        }

        if (fileSize < maxFileSize) {
            // Enable submit button and remove any error message
            $('#button_fileUpload').prop('disabled', false);
            $('#lbl_uploadMessage').text('');
        } else {
            // Disable submit button and show error message
            $('#button_fileUpload').prop('disabled', true);
            $('#lbl_uploadMessage').text('File too big !');
        }
    });
});

// Check if the browser is Internet Explorer
function isIE() {
    var myNav = navigator.userAgent.toLowerCase();
    return (myNav.indexOf('msie') != -1) ? parseInt(myNav.split('msie')[1]) : false;
} 

Warning!

Before blindly copying this code, note that the ActiveX solution is really a poor one. To make it work, the user must change its Internet Options. Also, this solution is no good for public sites, only for intranet apps.

But I am wondering if there is a more reliable method than ActiveX?

No, there is not for IE < 10

Second solution (jQuery plugin)

You could the jQuery File Upload. You can easily get the size with it.

Third solution (server side - VB.NET)

Considering you have these asp controls:

<asp:FileUpload ID="fileUpload" runat="server" />
<asp:Button ID="button_fileUpload" runat="server" Text="Upload File" />
<asp:Label ID="lbl_uploadMessage" runat="server" Text="" ForeColor="Red" />

You can check the chose file size once there is an interaction with the server side. For instance, here I am checking the file's size once the user clicks on the Upload Button.

Protected Sub btnFileUpload_click(ByVal sender As Object, ByVal e As System.EventArgs) Handles button_fileUpload.Click
    ' A temporary folder
    Dim savePath As String = "c:\temp\uploads\"
    If (fileUpload.HasFile) Then
        Dim fileSize As Integer = fileUpload.PostedFile.ContentLength
        ' 1MB -> 1000 * 1024
        If (fileSize < 1024000) Then
            savePath += Server.HtmlEncode(fileUpload.FileName)

            fileUpload.SaveAs(savePath)

            lbl_uploadMessage.Text = "Your file was uploaded successfully."

        Else
            lbl_uploadMessage.Text = "Your file was not uploaded because " +
                                     "it exceeds the 1 MB size limit."
        End If
    Else
        lbl_uploadMessage.Text = "You did not specify a file to upload."
    End If
End Sub

Edit

As you said, this last solution doesn't work with files which are too big. To allow this solution to work, you must increase the max upload file size in your web.config file:

<configuration>
    <system.web>
        <httpRuntime maxRequestLength="52428800" /> <!--50MB-->
    </system.web>
</configuration>
Community
  • 1
  • 1
actaram
  • 2,038
  • 4
  • 28
  • 49
  • Very nice. Thank you! I already had your VB method already in use. However if the file was too large it would skip the check for some reason, which is why I wanted to validate on the client side. I just saw your edit lol . I will ask IS if they will increase it(we are not suppose to touch it). I actually found a jQuery plugin that works very simular to the one you supplied. I have it implemented now as well. And lastly, thanks for the ActiveX solution. I will be using that for IE <10. Again Thank you so much. Luckily it is for our intranet so it should not be a problem. – Christian4423 May 28 '15 at 15:09
  • 1
    @Christian4423 You are very welcome. If you encounter any problems with the ActiveX solution, you can comment here and I'll be glad to help. – actaram May 28 '15 at 15:16
  • One quick thing. In your line `var AxFSObjFile = AxFSObj.getFile(filePath);` I am getting this error in my console _Invalid procedure call or argument_ I noticed that filePath is undefined. I tried `filePath = document.getElementById("File1").value` but no luck, still returned undefined. – Christian4423 May 28 '15 at 15:31
  • 1
    I got it working with $("File1").val() Thanks again! – Christian4423 May 28 '15 at 15:40
  • 1
    You are using ASP.NET, so I think the problem is that it doesn't find any element with and id of "File1", since ASP.NET generate another ID. With jQuery, you can do it as you did. But if you want to use JavaScript, you must use `document.getElementById('<%=File1.ClientID %>').value` or set the `fileUpload.ClientIDMode` to `Static`. Good job on finding a solution on your own. – actaram May 28 '15 at 15:43
  • 1
    Thanks man! I will use your `document.getElementById('<%=File1.ClientID %>').value` as I believe that pure JS is always better. I now have the solution working in every browser. :) – Christian4423 May 28 '15 at 16:19