0

I am using a asp file uploader by which i am uploading an image on a button click .whenever i am uploading an image over 4 mb it crashes .if i define a size in config for maxrequestlength then if i exceed the file size again it crashes.Is it possible to restrict user and show a disclaimer message if a huge file is uploaded . My intension is to let the user know that file is huge .

aspx page

<tr>
                    <td align="center" class="title" colspan="2">
                        Image Upload
                    </td>
                </tr>
                <tr>
                    <td align="center" colspan="2">
                        <asp:Label ID="lblImageDisclaimer" runat="server" Text="Please upload an image file less than 3MB in size"
                            Font-Bold="true" ForeColor="Highlight"></asp:Label>
                    </td>
                </tr>
                <tr>
                    <td align="center" colspan="2">
                        <asp:DropDownList ID="ddlImageType" runat="server" AutoPostBack="false" OnSelectedIndexChanged="ddlImageType_SelectedIndexChanged">
                        </asp:DropDownList>
                    </td>
                </tr>
                <tr>
                    <td align="center" colspan="2" id="tdUpload" runat="server">
                        <asp:Label ID="lblImage1" runat="server" Text="Upload images : " Font-Bold="true"></asp:Label>
                        &nbsp;
                        <asp:FileUpload ID="fileUploader" runat="server" /><asp:Button ID="btnUpload" CssClass="button"
                            runat="server" Text="Upload" OnClick="btnUpload_Click" OnClientClick="javascript:return validateFile();" />
                        <asp:Label ID="lblMessage" runat="server" Text="" CssClass="errorText"></asp:Label>
                    </td>
                </tr>
                <tr>
                    <td id="Td2" runat="server" align="center" colspan="1">
                        <asp:Label ID="Label1" runat="server" Text="SCREENSHOT 1" Font-Bold="true"></asp:Label>
                    </td>
                    <td id="Td3" runat="server" align="center" colspan="1">
                        <asp:Label ID="Label2" runat="server" Text="SCREENSHOT 2" Font-Bold="true"></asp:Label>
                    </td>
                </tr>
                <tr>
                    <td id="imgHolder" runat="server" align="center" colspan="1">
                        <div style="border: SOLID 1px BLACK; width: 575px; height: 250px; overflow: auto;">
                            <%--<asp:Image ID="imgPreview" runat="server" ImageUrl="~/FIRE/ImageHandler.ashx?id=1&imageNo=2" />--%>
                            <asp:Image ID="imgPreview" runat="server" />
                        </div>
                    </td>
                    <td id="imgHolder2" runat="server" align="center" colspan="1">
                        <div style="border: SOLID 1px BLACK; width: 575px; height: 250px; overflow: auto;">
                            <%--<asp:Image ID="imgPreview" runat="server" ImageUrl="~/FIRE/ImageHandler.ashx?id=1&imageNo=2" />--%>
                            <asp:Image ID="imgPreview2" runat="server" />
                        </div>
                    </td>
                </tr>
                <tr>
                    <td id="tdDelete1" align="left" style="width: 100%; padding-left: 15px;" colspan="1">
                        <asp:Button ID="btnDelete1" runat="server" Text="Delete" CssClass="button" OnClick="btnDelete_Click"
                            ToolTip="Click to Delete" OnClientClick="javascript:return  confirm('Are you sure you want to delete this image?');" />
                    </td>
                    <td id="tdDelete2" align="left" style="width: 100%" colspan="1">
                        <asp:Button ID="btnDelete2" runat="server" Text="Delete" CssClass="button" OnClick="btnDelete_Click"
                            ToolTip="Click to Delete" OnClientClick="javascript:return  confirm('Are you sure you want to delete this image?');" />
                    </td>
                </tr>

.cs page events. protected void btnUpload_Click(object sender, EventArgs e) { try { //hfCurrentId.Value = "Work item id: " + hfWorkItemID.Value; if (fileUploader.HasFile) { if (fileUploader.PostedFile.ContentType.Contains("image") && fileUploader.PostedFile.ContentLength <= 3145728) {

                    if (ddlImageType.SelectedValue == "1")
                    {
                        Session["FileBytes"] = fileUploader.FileBytes;
                        hfImage1Byte.Value = Convert.ToBase64String(fileUploader.FileBytes);
                        imgPreview.ImageUrl = "~/Handlers/ImageHandler.ashx?workItemId=" + workItemId
                        + "&imageTypeId=" + ddlImageType.SelectedValue;
                    }
                    else
                    {
                        Session["FileBytes2"] = fileUploader.FileBytes;
                        hfImage2Byte.Value = Convert.ToBase64String(fileUploader.FileBytes);
                        imgPreview2.ImageUrl = "~/Handlers/ImageHandler.ashx?workItemId=" + workItemId
                        + "&imageTypeId=" + ddlImageType.SelectedValue;
                    }


                }
                else
                {
                    lblMessage.Text = Constants.ImageFileError;
                }
            }
            else
            {
                lblMessage.Text = Constants.FileError;
            }
            //lblHeader.Text = hfCurrentId.Value;
            //upPanel1.Update();
        }
        catch (System.Exception ex)
        {
            //DisplayError(ex);
            Session["ExceptionDetails"] = ex;
            Response.Redirect(Constants.FIREErrorDetails);
        }
    }

Here i am limiting the size by 3145728 and handling it in client size

function validateFile() {
            var strFileName = document.getElementById('<%=fileUploader.ClientID %>').value;
            var strExtName = strFileName.substring(strFileName.lastIndexOf('.')).toLowerCase();
            var objFSO = new ActiveXObject("Scripting.FileSystemObject");
            var e = objFSO.getFile(strFileName);
            var fileSize = e.size;
            //file size limit for 3mb
            if (fileSize > 3145728) {
                alert("Maximum size of uploaded file should be less than 3 MB.");
                return false;
            }
            else
                return true;
        }

is there any other way to avoid

var objFSO = new ActiveXObject("Scripting.FileSystemObject");

I can't use ActiveXObject as per some client issue

Rahul Chowdhury
  • 1,138
  • 6
  • 29
  • 52

2 Answers2

3

Assuming that you are not using HTML5. Assuming you are not using custom/third-party components as suggested by Karl.

(1) You will need to first limit the upload size in web.config for IIS:

<system.webServer>
    <security>
        <requestFiltering>
            <requestLimits maxAllowedContentLength="YOUR_MAX_ALLOWED_SIZE IN BYTES"/>
        </requestFiltering>
    </security>
</system.webServer>

(2) Make sure the values are matching in httpRuntime for ASP.Net:

<httpRuntime executionTimeout="SECONDS" maxRequestLength="YOUR_MAX_ALLOWED_SIZE IN KB"/>

(3) Check if the size exceeds in your server-side code and suitably inform the user:

if (fileUpload.PostedFile.ContentLength > (YOUR_MAX_ALLOWED_SIZE - n)) {
    // where "n" is arbitrary number to intercept uploads before IIS kicks it
    // you display limit to users as (YOUR_MAX_ALLOWED_SIZE - n)
    // inform problem to the user here
}

You cannot check it at the client-side unless you are using HTML5 File API. So, the user has to wait until the entire file is uploaded and then it is maxed out. Hence, set your YOUR_MAX_ALLOWED_SIZE carefully.

Update:

As you see, it is difficult to catch if the size exceeds the limit. There a few workarounds:

  1. Set up custom errors:

  2. Setup httpErrors in system.webServer section:

See the accepted answer by Marcus here: Display custom error page when file upload exceeds allowed size in ASP.NET MVC

Community
  • 1
  • 1
Abhitalks
  • 27,721
  • 5
  • 58
  • 81
1

The short answer is no you cannot use code to catch to large of a file and inform the user, because the IIS setting is checked before any of your code will execute, thus it is too late.

If you want a better user experience, then I suggest you investigate some open source solutions like the following:

  1. Custom HTTP module

    NeatUpload is a free option.

  2. Silverlight/Flash option

    SWFUpload is a free option.

  3. Asynchronous chunking option

    RadAsyncUpload - Telerik's ASP.NET AsyncUpload is a pay option, check website for pricing.

Karl Anderson
  • 34,606
  • 12
  • 65
  • 80
  • Can i do it with AjaxFileUploader ? – Rahul Chowdhury Jul 29 '13 at 14:30
  • If you are exclusively targeting HTML5 browsers, then yes you could get the file size prior to uploading by using the `HTML5 File API`, but if you have any users using an HTML4-based browser then this will go out the window. If you read the documentation for the ASP.NET AJAX AjaxFileUploader, it says that it requires HTML5 for the progress feedback; otherwise it shows a spinner. So it really comes down to HTML5 or not; HTML5 opens up a lot of possibilities, but beware that not all versions of IE support all of the HTML5 capabilities; check out [Can I Use](http://caniuse.com/) website. – Karl Anderson Jul 29 '13 at 14:37