2009-11-27 103 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