捕捉到“超出最大请求长度”


112

我正在编写一个上载函数,并且遇到文件大于httpRuntimeweb.config中指定的最大大小(最大大小设置为5120)时,捕获“ System.Web.HttpException:超出最大请求长度”的问题。我正在使用一个简单<input>的文件。

问题是该异常在上载按钮的单击事件之前引发,并且该异常在我的代码运行之前发生。那么,如何捕获和处理异常?

编辑:异常立即引发,所以我很确定这不是由于连接速度慢而引起的超时问题。


5
有人尝试过MVC吗?我似乎能够以正确的方式捕获异常,但是我无法阻止它:每次尝试渲染错误页面时,都会发生相同的异常。
安迪

IIS在到达控制器之前会引发此错误消息。要通知用户文件已超过最大上传限制(在您的网络配置中设置),您可以通过带有onchange事件的JS直接验证文件大小。对于例如<input type="file" id="upload" name="upload" onchange="showFileSize();" />Inside showFileSize(),您可以通过var input = document.getElementById("upload"); var file = input.files[0];并添加html标记显示基于文件大小的错误消息。
阿尔弗雷德·华莱士

Answers:


97

不幸的是,没有简单的方法来捕获此类异常。我要做的是要么在页面级别覆盖OnError方法,要么在global.asax中覆盖Application_Error,然后检查它是否是最大请求失败,如果是,则转移到错误页面。

protected override void OnError(EventArgs e) .....


private void Application_Error(object sender, EventArgs e)
{
    if (GlobalHelper.IsMaxRequestExceededException(this.Server.GetLastError()))
    {
        this.Server.ClearError();
        this.Server.Transfer("~/error/UploadTooLarge.aspx");
    }
}

这是一个hack,但是下面的代码对我有用

const int TimedOutExceptionCode = -2147467259;
public static bool IsMaxRequestExceededException(Exception e)
{
    // unhandled errors = caught at global.ascx level
    // http exception = caught at page level

    Exception main;
    var unhandled = e as HttpUnhandledException;

    if (unhandled != null && unhandled.ErrorCode == TimedOutExceptionCode)
    {
        main = unhandled.InnerException;
    }
    else
    {
        main = e;
    }


    var http = main as HttpException;

    if (http != null && http.ErrorCode == TimedOutExceptionCode)
    {
        // hack: no real method of identifying if the error is max request exceeded as 
        // it is treated as a timeout exception
        if (http.StackTrace.Contains("GetEntireRawContent"))
        {
            // MAX REQUEST HAS BEEN EXCEEDED
            return true;
        }
    }

    return false;
}

2
谢谢。OnError不起作用,但Application_Error起作用。我们实际上有一个处理程序,但是有人在代码中将其关闭。
Marcus L

即使在两年前,但我仍然想问一下,到现在为止是否还行得通?'GetEntireRawContent'的字符串比较工作正常吗?我认为这不是超时问题。有没有人特别指出我在这方面的阴天?
伊莱恩(Elaine)

@Elaine是的,这项技术仍可用于ASP.Net 4.0。如果尝试上载大于最大请求长度的请求,则ASP.Net会引发带有超时代码的HttpException。使用反射器查看System.Web.HttpRequest.GetEntireRawContent()。
Damien McGivern

12
@ sam-rueby我不想回复由于本地化而可能更改的字符串错误消息。
Damien McGivern

4
对于.NET 4.0及更高版本,有一种更好的方法来确定是否超出了最大请求大小。您可以检查HttpException的这种情况:httpException.WebEventCode == WebEventCodes.RuntimeErrorPostTooLarge-使用System.Web.Management.WebEventCodes
mco,2015年

58

正如GateKiller所说的,您需要更改maxRequestLength。如果上载速度太慢,您可能还需要更改executionTimeout。请注意,您不希望这些设置中的任何一个太大,否则您将容易受到DOS攻击。

executeTimeout的默认值为360秒或6分钟。

您可以使用httpRuntime元素更改maxRequestLength和executionTimeout 。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <httpRuntime maxRequestLength="102400" executionTimeout="1200" />
    </system.web>
</configuration>

编辑:

如果要处理该异常,无论如何(如上所述),都需要在Global.asax中进行处理。这是代码示例的链接。


2
感谢您的答复,但是正如我在对GK的答复的评论中所说,这并不能真正解决我的问题。这也不是超时问题,因为异常会立即抛出。我将编辑问题以使其更清楚。
Marcus L

4
代码示例网址指向的页面不可用...任何人都可以解决此问题吗?
deostroll

20

您可以通过增加web.config中的最大请求长度来解决此问题:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <httpRuntime maxRequestLength="102400" />
    </system.web>
</configuration>

上面的示例是100Mb的限制。


18
是的,没有。您将限制进一步提高,但它不能真正处理异常。如果有人尝试上传101+ Mb,您仍然会遇到同样的问题。限制确实需要为5 Mb。
Marcus L

10

如果您还希望进行客户端验证,那么就不需要抛出异常,可以尝试实现客户端文件大小验证。

注意:这仅在支持HTML5的浏览器中有效。 http://www.html5rocks.com/zh-CN/tutorials/file/dndfiles/

<form id="FormID" action="post" name="FormID">
    <input id="target" name="target" class="target" type="file" />
</form>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>

<script type="text/javascript" language="javascript">

    $('.target').change(function () {

        if (typeof FileReader !== "undefined") {
            var size = document.getElementById('target').files[0].size;
            // check file size

            if (size > 100000) {

                $(this).val("");

            }
        }

    });

</script>


9

达米安·麦吉文(Damien McGivern)提到的嗨解决方案,仅适用于IIS6,

它不适用于IIS7和ASP.NET开发服务器。我得到的页面显示“ 404-找不到文件或目录”。

有任何想法吗?

编辑:

知道了...该解决方案仍然无法在ASP.NET Development Server上运行,但是我知道在我的情况下它无法在IIS7上运行的原因。

原因是IIS7具有内置的请求扫描功能,该功能强加了一个默认为30000000字节(略小于30MB)的上传文件上限。

而且我正在尝试上传大小为100 MB的文件以测试Damien McGivern提到的解决方案(maxRequestLength =“ 10240”,即web.config中为10MB)。现在,如果我上传的文件大小> 10MB且<30 MB,则该页面将重定向到指定的错误页面。但是,如果文件大小> 30MB,则会显示难看的内置错误页面,显示“ 404-找不到文件或目录”。

因此,为避免这种情况,您必须增加最大值。IIS7中网站允许的请求内容长度。可以使用以下命令来完成,

appcmd set config "SiteName" -section:requestFiltering -requestLimits.maxAllowedContentLength:209715200 -commitpath:apphost

我已经设定了最高 内容长度为200MB。

进行此设置后,当我尝试上传100MB的文件时,页面成功重定向到我的错误页面

有关更多详细信息,请参考http://weblogs.asp.net/jgalloway/archive/2008/01/08/large-file-uploads-in-asp-net.aspx


抱歉! 我已将查询添加为答案,不知道如何在现有帖子中添加评论。
Vinod T. Patil,2010年

1
您只需要更多代表。评论帖子。请参阅常见问题,以了解有关您当前代表可以做什么/不能做什么的更多详细信息。
slaphappy

7

这是另一种方法,它不涉及任何“黑客”,但需要ASP.NET 4.0或更高版本:

//Global.asax
private void Application_Error(object sender, EventArgs e)
{
    var ex = Server.GetLastError();
    var httpException = ex as HttpException ?? ex.InnerException as HttpException;
    if(httpException == null) return;

    if(httpException.WebEventCode == WebEventCodes.RuntimeErrorPostTooLarge)
    {
        //handle the error
        Response.Write("Sorry, file is too big"); //show this message for instance
    }
}

4

一种方法是如上所述在web.config中设置最大大小,例如

<system.web>         
    <httpRuntime maxRequestLength="102400" />     
</system.web>

然后在处理上传事件时,检查大小,如果大小超过特定数量,则可以将其捕获

protected void btnUploadImage_OnClick(object sender, EventArgs e)
{
    if (fil.FileBytes.Length > 51200)
    {
         TextBoxMsg.Text = "file size must be less than 50KB";
    }
}

1
这行不通。点击事件永远不会触发。例外发生在之前。
隆巴斯'17


3

在IIS 7及更高版本中:

web.config文件:

<system.webServer>
  <security >
    <requestFiltering>
      <requestLimits maxAllowedContentLength="[Size In Bytes]" />
    </requestFiltering>
  </security>
</system.webServer>

然后,您可以在后面签入代码,如下所示:

If FileUpload1.PostedFile.ContentLength > 2097152 Then ' (2097152 = 2 Mb)
  ' Exceeded the 2 Mb limit
  ' Do something
End If

只需确保web.config中的[字节大小]大于您要上传的文件的大小,就不会出现404错误。然后,您可以使用ContentLength在后面的代码中检查文件大小,这会更好


2

您可能知道,最大请求长度是在两个地方配置的。

  1. maxRequestLength -在ASP.NET应用程序级别进行控制
  2. maxAllowedContentLength-在<system.webServer>IIS级别下控制

第一种情况包含在此问题的其他答案中。

要捕获第二个,您需要在global.asax中执行以下操作:

protected void Application_EndRequest(object sender, EventArgs e)
{
    //check for the "file is too big" exception if thrown at the IIS level
    if (Response.StatusCode == 404 && Response.SubStatusCode == 13)
    {
        Response.Write("Too big a file"); //just an example
        Response.End();
    }
}

1

后标签

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

添加以下标签

 <httpErrors errorMode="Custom" existingResponse="Replace">
  <remove statusCode="404" subStatusCode="13" />
  <error statusCode="404" subStatusCode="13" prefixLanguageFilePath="" path="http://localhost/ErrorPage.aspx" responseMode="Redirect" />
</httpErrors>

您可以将网址添加到错误页面...


0

您可以通过在web.config中增加最大请求长度和执行超时来解决此问题:

-请澄清最大执行超时磨碎机然后1200

<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <httpRuntime maxRequestLength="102400" executionTimeout="1200" /> </system.web> </configuration>

0

如何在EndRequest事件中捕获它?

protected void Application_EndRequest(object sender, EventArgs e)
    {
        HttpRequest request = HttpContext.Current.Request;
        HttpResponse response = HttpContext.Current.Response;
        if ((request.HttpMethod == "POST") &&
            (response.StatusCode == 404 && response.SubStatusCode == 13))
        {
            // Clear the response header but do not clear errors and
            // transfer back to requesting page to handle error
            response.ClearHeaders();
            HttpContext.Current.Server.Transfer(request.AppRelativeCurrentExecutionFilePath);
        }
    }

0

可以通过以下方式检查:

        var httpException = ex as HttpException;
        if (httpException != null)
        {
            if (httpException.WebEventCode == System.Web.Management.WebEventCodes.RuntimeErrorPostTooLarge)
            {
                // Request too large

                return;

            }
        }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.