2009-11-27 73 views
3

Asp.Net对文件上传有一个上限。我试图在服务器端捕捉到这种情况。根据我发现的文档,应该可以覆盖Global.asax中的Application_Error,但它不适用于我。第二种选择是重写接收页面的OnError,但这也不起作用。抓取大文件上传

任何人都可以显示一些工作代码,如何在服务器端捕获此错误?

回答

0

而不是捕获错误不能检查文件的大小与web.config文件中指定的最大大小?您可以使用以下方法来获取最大尺寸:“任何人都可以显示在 一些工作代码如何抓住这个错误在服务器端 ”

System.Configuration.Configuration config = WebConfigurationManager.OpenWebConfiguration("~"); 
HttpRuntimeSection section = config.GetSection("system.web/httpRuntime") as HttpRuntimeSection; 
double maxFileSize = section.MaxRequestLength; 
+1

由于IIS拦截了上次的上传,所以永远不会到达该代码。 – Achim 2009-11-27 11:18:05

+0

取决于你把上面的代码放在哪里? – Fermin 2009-11-27 11:31:06

+2

你可以把上面的代码放在哪里? – Rod 2012-05-08 21:05:38

0

没有。无法使用代码来捕获此错误,因为它在任何代码启动之前发生。

据我发现,你甚至不能指定一个替代的错误页面这个错误,Web服务器拒绝接受请求时,它太大。

+0

如果我增加web.config中的最大上传大小,它工作正常。所以上传必须被asp.net运行时的一部分拦截。然后它应该有可能以某种方式捕捉到这一点。你同意吗? – Achim 2009-11-27 11:19:27

+0

@Achim:如果您将限制设置得如此之高,以至实际上删除了限制,您可以在代码中进行检查,但您的服务器很容易受到DoS攻击。有人可能会启动一些大型上传,并会耗尽服务器中的所有RAM。 – Guffa 2009-11-27 13:14:55

+0

不,这取决于执行代码的位置和时间。我说的是:如果限制在asp.ne运行时中配置,那么它也在asp.net运行时中处理。所以请求至少达到asp.net并且在此之前不被IIS阻止。然后它应该有可能以某种方式在asp.net中捕获它。根据我提到的地方应该可能的文件 - 但它不! – Achim 2009-11-27 14:37:28

1

Uploadify是一个jQuery和Flash上​​载程序,允许您指定要下载的文件的最大大小。这样,您可以防止用户首先下载文件,并且不必担心会在后面捕获该文件。

2

放在Golobal.asax.cs如下:

void Application_Error(Object sender, EventArgs e) 
     { 
      HttpException ex = Server.GetLastError() as HttpException; 
      if (ex != null) 
      { 
       if ((ex.GetHttpCode() == 500 || ex.GetHttpCode() == 400) && ex.ErrorCode == -2147467259) 
       { 
        Server.ClearError(); 
        Response.Redirect("~/MaximumFileError.aspx", false); 
       } 
      } 
     } 

这为我工作,但我不知道这是否适用于所有情况。

0

首先您应该了解一些关于maxRequestLength的内容。使用服务器端方法验证无法预测文件大小。将值设置为高会增加DoS攻击的风险。 我在web.config中的maxRequestLength设置为8MB:

<httpRuntime maxRequestLength="8192" executionTimeout="3600" /> 

我在形式上我的代码隐藏检查,如果用户上传的文件是不是比在maxRequestLength的一半给予更大,但这种检查可能永远如果发生上传文件的大小大于web.config中指定的最大RequestLength,因为将抛出异常。这种例外应该赶上Global.asax的水平。在那里我检查Exception是否包含标识我们问题的单词,因为System.Web.HttpUnhandledException在很多其他情况下可能会抛出!良好的提示可能是检查异常来自哪个页面,以确保我们处理某种形式,通过将用户重定向到表单重要的是什么。

void Application_Error(object sender, EventArgs e){ 
Exception wyjatek = Server.GetLastError(); 
     if (wyjatek.InnerException != null && wyjatek.InnerException.Message.Contains("Maximum request length exceeded")) 
     { 
      Server.ClearError(); 
      Response.Redirect("FormWithFile.aspx?alert=Za-duzy-plik"); 
     } 
    } 

如果我在Global.asax中发现这个异常,我将用户重定向到带有alert的页面(在GET中给出)。

在ASPX页面我的后台代码:

首先,我从网上retrive的maxRequestLength的值。配置通过此树线,一半是:

static System.Configuration.Configuration config = WebConfigurationManager.OpenWebConfiguration("~"); 
static HttpRuntimeSection section = config.GetSection("system.web/httpRuntime") as HttpRuntimeSection; 
int maxFileSize = (section.MaxRequestLength/2)*1024; 

然后在插入按钮连接动作,我进行如下操作:

protected void InsertButton_Click(object sender, EventArgs e) 
     { 
      if (((FileUpload)FormView1.FindControl("FileUpload1")).HasFile) // WHEN USER WANT TO UPLOAD FORM WITH FILE (its, optional) 
      { 
       HttpPostedFile file = (HttpPostedFile)(((FileUpload)FormView1.FindControl("FileUpload1")).PostedFile); 
       int iFileSize = file.ContentLength; 
       if ((file != null) && (file.ContentLength > 0)) 
       { 
        if (iFileSize > maxFileSize) // checking image SIZE! 
        { 
         MessageForUser.Text = "<h1 class=error>Bad File! File is to big!</h1>"; 
        } 
        else 
        { 
         byte[] plik = ((FileUpload)FormView1.FindControl("FileUpload1")).FileBytes; 
       // HERE COMES CODE FOR INSERT OF FORM WITH FILE 
         MessageForUser.Text = "<h1>Insert was sucessfull</h2>"; 
        } 
       } 
      } 
      else 
      { 
       // HERE COMES CODE FOR INSERT OF FORM WITHOUT FILE 
       MessageForUser.Text = "<h1>Insert was sucessfull</h2>"; 
     } 
    } 

在Page_Load中我也定义了如何以检索通信。通过GET从给定Global.asax,通知用户什么发生。

if (Request.QueryString["alert"]!=null) 
      { 
       string temp = Request.QueryString["alert"].Replace('-',' '); 
       MessageForUser.Visible = true; 
       MessageForUser.Text = "<h1 class=error>ERROR: " + temp + "</h1>"; 
      } 

该解决方案当然有它的缺点:

  1. 不过,我们可以在DoS攻击有8MB的文件,我们首先承认在服务器的水平,什么是已经很晚了。
  2. 在Global.asax重定向的情况下,用户表单的状态会丢失,但可以克服这一点代码。
  3. 由于在服务器端进行检查以及许多用户的负载,用户查验会相当差,应用程序可能变得很慢。
  4. 即暂时服务器来的文件比8MB更大,但这样其管理executionTimeout

可能的备选方案:

  1. 使用一些flash技术,检查客户端上的文件大小
  2. 使用一些流技术,以小包的形式传输叮咬,并且在达到给定阈值的那一刻,抛出自己的异常并处理它。 适当的阅读:Sending File in Chunks to HttpHandler