问题是异常在上传按钮的点击事件之前被抛出,而这个异常发生在我的代码运行之前。那么我该如何捕获和处理这个异常?
编辑:异常是立即抛出的,所以我很确定这不是由于网络连接较慢而导致的超时问题。
很遗憾没有简单的方法可以捕获这种异常。我的做法是要么在页面级别覆盖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");
}
}
这并不是正式的解决方案,但以下代码对我有效
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;
}
httpException.WebEventCode == WebEventCodes.RuntimeErrorPostTooLarge
- 使用 System.Web.Management.WebEventCodes - mco如GateKiller所说,您需要更改maxRequestLength。如果上传速度太慢,您可能还需要更改executionTimeout。请注意,您不希望这两个设置过大,否则您将容易受到DOS攻击。
executionTimeout的默认值为360秒或6分钟。
您可以使用httpRuntime Element更改maxRequestLength和executionTimeout。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<httpRuntime maxRequestLength="102400" executionTimeout="1200" />
</system.web>
</configuration>
编辑:
如果您想无论如何处理异常,那么就像已经提到的那样,您需要在Global.asax中处理它。这里是一个代码示例链接。
您可以通过增加web.config文件中的最大请求长度来解决此问题:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<httpRuntime maxRequestLength="102400" />
</system.web>
</configuration>
上面的示例是为了100Mb的限制而设定的。
<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>
嗨,Damien McGivern提到的解决方案只适用于IIS6,
它在IIS7和ASP.NET开发服务器上无法运行。我看到“404-文件或目录未找到”页面。
有什么想法吗?
编辑:
明白了...这个解决方案仍然不适用于ASP.NET开发服务器,但我知道为什么在我的情况下它不能在IIS7上运行了。
原因是IIS7具有内置的请求扫描功能,强制实施上传文件大小限制,默认为30000000字节(略小于30MB)。
我试图上传100MB大小的文件以测试Damien McGivern提到的解决方案(web.config中的maxRequestLength =“10240”即10MB)。现在,如果我上传的文件大小大于10MB且小于30MB,则页面将重定向到指定的错误页面。但是,如果文件大小大于30MB,则会显示丑陋的内置错误页面,显示“404-文件或目录未找到”。
因此,为避免这种情况,您必须增加IIS7网站的最大允许请求内容长度。
可以使用以下命令来完成:
appcmd set config "SiteName" -section:requestFiltering -requestLimits.maxAllowedContentLength:209715200 -commitpath:apphost
这里有一种替代方式,不涉及任何“黑科技”,但需要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
}
}
其中一种方法是在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";
}
}
在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中的[Size In Bytes]大于您要上传的文件大小,这样就不会发生404错误。然后您可以在代码后台使用ContentLength检查文件大小,这样会更好。
你可能已经知道了,最大请求长度在两个地方进行配置。
maxRequestLength
- 在 ASP.NET 应用程序层面进行控制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();
}
}
<input type="file" id="upload" name="upload" onchange="showFileSize();" />
在showFileSize()
内,您可以通过var input = document.getElementById("upload"); var file = input.files[0];
显示基于文件大小的错误消息并附加一个HTML标记。 - Alfred Wallace