2010-05-03 37 views
10

Tôi đang giới hạn người dùng kích thước tệp có thể tải lên trang web từ Web.config. Như được giải thích here, nó sẽ ném một ConfigurationErrorsException nếu kích thước không được chấp nhận. Tôi đã cố gắng để bắt nó từ các phương pháp hành động hoặc điều khiển cho các yêu cầu tải lên nhưng không có may mắn. Kết nối được đặt lại và tôi không thể hiển thị kết nối đó để hiển thị trang lỗi.Làm thế nào để bắt ConfigurationErrorsException cho vi phạm maxRequestLength?

Tôi đã cố gắng bắt nó trong sự kiện BeginRequest nhưng không có vấn đề gì tôi làm ngoại lệ là unhandled. Dưới đây là các mã:

protected void Application_BeginRequest(Object sender, EventArgs e) 
{ 
    HttpContext context = ((HttpApplication)sender).Context; 
    try 
    { 
     if (context.Request.ContentLength > maxRequestLength) 
     { 
      IServiceProvider provider = (IServiceProvider)context; 
      HttpWorkerRequest workerRequest = (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest)); 

      // Check if body contains data 
      if (workerRequest.HasEntityBody()) 
      { 
       // get the total body length 
       int requestLength = workerRequest.GetTotalEntityBodyLength(); 
       // Get the initial bytes loaded 
       int initialBytes = 0; 
       if (workerRequest.GetPreloadedEntityBody() != null) 
        initialBytes = workerRequest.GetPreloadedEntityBody().Length; 
       if (!workerRequest.IsEntireEntityBodyIsPreloaded()) 
       { 
        byte[] buffer = new byte[512]; 
        // Set the received bytes to initial bytes before start reading 
        int receivedBytes = initialBytes; 
        while (requestLength - receivedBytes >= initialBytes) 
        { 
         // Read another set of bytes 
         initialBytes = workerRequest.ReadEntityBody(buffer, buffer.Length); 

         // Update the received bytes 
         receivedBytes += initialBytes; 
        } 
        initialBytes = workerRequest.ReadEntityBody(buffer, requestLength - receivedBytes); 
       } 
      } 
     } 
    } 
    catch(HttpException) 
    { 
     context.Response.Redirect(this.Request.Url.LocalPath + "?action=exception"); 
    } 
} 

Nhưng tôi vẫn có được điều này:

Maximum request length exceeded. 

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Web.HttpException: Maximum request length exceeded. 

Source Error: 

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. 

Cập nhật:

phương pháp gì làm tăng ngoại lệ không? Nếu tôi đọc yêu cầu, nó làm tăng ngoại lệ Nếu tôi không đọc nó, tôi nhận được "101 Connection Reset" trong trình duyệt. Có thể làm gì ở đây?

+0

Tôi muốn làm theo câu trả lời của bạn, tôi googled nó và thấy điều này: http://stackoverflow.com/questions/2966076/get-file-size-in-javascript. Theo chủ đề này, không có cách nào để tìm ra kích thước tệp thông qua Javascript đơn giản (tôi không muốn sử dụng Flash, ActiveX hoặc HTML 5!). Tôi có hiểu chính xác không? – celticharp

+0

@necronio Tôi nghĩ vậy. –

Trả lời

1

Không có cách nào để làm điều đó ngay mà không có sự trợ giúp của phía máy khách. Bạn không thể xác định xem yêu cầu có quá dài hay không trừ khi bạn đọc tất cả. Nếu bạn đọc từng yêu cầu đến cùng, mọi người đến và giữ máy chủ của bạn bận. Nếu bạn chỉ cần nhìn vào chiều dài nội dung và thả yêu cầu, phía bên kia sẽ nghĩ rằng có một vấn đề kết nối. Đó là không có gì bạn có thể làm với xử lý lỗi, đó là một thiếu sót của HTTP.

Bạn có thể sử dụng các thành phần Flash hoặc Javascript để làm cho nó phù hợp bởi vì điều này không thể thất bại độc đáo.

5

Bạn không thể lỗi catch trong phương pháp hành động becouse ngoại lệ đến trước đó, nhưng bạn có thể bắt nó ở đây

protected void Application_Error() { 
    var lastError = Server.GetLastError(); 
    if(lastError !=null && lastError is HttpException && lastError.Message.Contains("exceed")) { 
     Response.Redirect("~/errors/RequestLengthExceeded"); 
     } 
    } 

Actualy khi kích thước tập tin vượt quá giới hạn HttpException lỗi phát sinh.

Ngoài ra còn có giới hạn IIS về nội dung - không thể bị bắt trong ứng dụng. IIS 7 ném

Lỗi HTTP 404,13 - Not Found Các module lọc yêu cầu được cấu hình để từ chối một yêu cầu vượt quá chiều dài nội dung yêu cầu.

Bạn có thể google, có rất nhiều thông tin về lỗi này.

+0

Tôi chưa lưu trữ nó trên IIS. Tôi đang thử nó trên máy chủ phát triển nhưng tôi sẽ ghi nhớ. Tôi giả sử tôi nên xử lý nó từ global.asax? –

+0

Có, từ global.asax –

+0

Thật lạ. Tôi quản lý để bắt lỗi nhưng tôi không thể chuyển hướng nó ở một nơi khác. Nó đi cho URL tải lên. Có vẻ như một người khác có [cùng một vấn đề] (http://forums.asp.net/p/845691/957981.aspx#957981) –

0

Tôi không chắc chắn 100% về điều này, nhưng tôi nghĩ rằng nó có thể giúp đỡ nếu bạn đã cố gắng thay đổi:

context.Response.Redirect(this.Request.Url.LocalPath + "?action=exception");

để

Server.Transfer(this.Request.Url.LocalPath + "?action=exception,false)

suy nghĩ của tôi là sự quá mức Yêu cầu độ dài yêu cầu tối đa vẫn đang được xử lý trong cuộc gọi Chuyển hướng nhưng nếu bạn yêu cầu nó bỏ qua dữ liệu biểu mẫu, nó sẽ trở thành dưới độ dài yêu cầu tối đa và sau đó nó có thể hoạt động khác nhau.

Không đảm bảo, nhưng dễ dàng kiểm tra.

+0

Server.Transfer không hoạt động trong MVC. Response.Redirect thực hiện điều tương tự. Vấn đề là trình duyệt nghĩ rằng có một vấn đề kết nối nếu bạn không đọc toàn bộ điều và ném 101 –

0
catch (Exception ex) 
    { 
     if (ex is HttpException && (ex as HttpException).WebEventCode == 3004) 
     { 
      //-- you can now inform the client that file uploaded was too large. 
     } 
     else 
      throw; 
    } 
0

Tôi gặp vấn đề tương tự ở chỗ tôi muốn nắm bắt ngoại lệ 'Yêu cầu tối đa vượt quá' ngoại lệ trong trình xử lý Application_Error và sau đó thực hiện chuyển hướng.

(Sự khác biệt là tôi đang viết dịch vụ REST với ASP.Net Web API và thay vì chuyển hướng đến trang lỗi, tôi muốn chuyển hướng đến bộ điều khiển lỗi, sau đó sẽ trả về phản hồi thích hợp).

Tuy nhiên, điều tôi thấy là khi chạy ứng dụng thông qua Máy chủ phát triển ASP.Net, Response.Redirect dường như không hoạt động. Fiddler sẽ tuyên bố "ReadResponse() không thành công: Máy chủ không trả lại phản hồi cho yêu cầu này".

Ứng dụng khách của tôi (Máy khách REST nâng cao dành cho Chrome) sẽ chỉ hiển thị "0 NO RESPONSE".

Nếu sau đó tôi chạy ứng dụng qua bản sao IIS cục bộ trên máy phát triển của tôi thì chuyển hướng sẽ hoạt động chính xác!

Tôi không chắc chắn tôi có thể dứt khoát nói rằng Response.Redirect không hoạt động trên Máy chủ phát triển ASP.Net nhưng chắc chắn nó không hoạt động trong tình huống của tôi.

Vì vậy, tôi khuyên bạn nên cố gắng chạy ứng dụng của mình thông qua IIS thay vì IIS Express hoặc Máy chủ phát triển và xem bạn có nhận được kết quả khác không.

Xem liên kết này về cách Xác định máy chủ Web cho các dự án Web trong Visual Studio:

http://msdn.microsoft.com/en-us/library/ms178108(v=vs.100).aspx

Các vấn đề liên quan