2011-07-13 32 views
21

Tôi đang sử dụng asp:FileUpLoad để tải tệp lên trong dự án asp.net c# của mình. Điều này tất cả hoạt động tốt miễn là kích thước tập tin không vượt quá tối đa cho phép. Khi vượt quá giới hạn tối đa. Tôi gặp lỗi "Internet Explorer cannot display the webpage". Vấn đề là khối catch try không bắt lỗi vì vậy tôi không thể cung cấp cho các user a friendly message rằng họ đã excced kích thước cho phép. Tôi đã thấy vấn đề này khi tìm kiếm trên web nhưng tôi không thể tìm thấy giải pháp có thể chấp nhận được.Tệp quá lớn khi tải lên tệp có asp: Kiểm soát FileUpLoad

Tôi sẽ xem xét các biện pháp kiểm soát khác, nhưng quản lý của tôi có thể sẽ không đi mua quyền kiểm soát của bên thứ ba.

Khi có câu trả lời gợi ý ajac, tôi cần thêm nhận xét này. Tôi đã thử tải các điều khiển ajax vài tháng trước. Ngay sau khi tôi sử dụng một điều khiển ajax, tôi nhận được lỗi biên dịch này.

Lỗi 98 Loại 'System.Web.UI.ScriptControl' được xác định trong một cụm không được tham chiếu. Bạn phải thêm tham chiếu đến assembly 'System.Web.Extensions, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = 31bf3856ad364e35'.

Tôi có thể loại bỏ nó mặc dù tôi đã thêm 'System.Web.Extensions'. Vì vậy, tôi đã bỏ rơi Ajax và sử dụng các kỹ thuật khác.

Vì vậy, tôi cần giải quyết vấn đề này hoặc giải pháp hoàn toàn mới.

Trả lời

0

Điều này có vẻ là vấn đề thời gian chờ của phiên, tăng thời gian phiên và sau đó thử lại. Bạn có thể đặt thời gian chờ của phiên trong tệp web.config

29

Giới hạn kích thước tệp mặc định là 4MB nhưng bạn có thể thay đổi giới hạn mặc định bằng cách thả tệp web.config vào thư mục chứa trang tải lên của bạn cuộc sống. Bằng cách đó bạn không phải làm cho toàn bộ trang web của bạn cho phép tải lên rất lớn (làm như vậy sẽ mở bạn đến một loại tấn công nhất định).

Chỉ cần đặt nó trong web.config trong phần <system.web>. ví dụ. Trong ví dụ dưới đây tôi đang thiết lập độ dài tối đa mà để 2GB

<httpRuntime maxRequestLength="2097152" executionTimeout="600" /> 

Xin lưu ý rằng maxRequestLength được thiết lập trong KB và nó có thể được thiết lập để 2GB (2079152 KB's). Thực tế, chúng tôi thường không cần đặt độ dài yêu cầu là 2GB, nhưng nếu bạn đặt độ dài yêu cầu cao hơn, chúng tôi cũng cần tăng số executionTimeout.

Execution Timeout Specifies the maximum number of seconds that a request is allowed to execute before being automatically shut down by ASP.NET. (Default time is 110 seconds.)

Đối với chi tiết xin vui lòng đọc httpRuntime Element (ASP.NET Settings Schema)

Bây giờ nếu bạn muốn hiển thị thông báo tùy chỉnh để sử dụng, nếu kích thước tập tin lớn hơn 100MB.

Bạn có thể làm điều đó như thế ..

if (FileUpload1.HasFile && FileUpload1.PostedFile.ContentLength > 104857600) 
{ 
    //FileUpload1.PostedFile.ContentLength -- Return the size in bytes 
    lblMsg.Text = "You can only upload file up to 100 MB."; 
} 
+1

Và xem tại đây để biết thêm errata: http://support.microsoft.com/kb/295626 –

+0

Tôi hiểu rằng tôi có thể tăng giới hạn, nhưng bất cứ điều gì tôi đặt ai đó có thể vượt quá nó. Tôi muốn cung cấp cho họ một thông điệp thân thiện trong trường hợp đó. –

+0

Trước khi tải lên (Lưu) tệp, bạn có thể kiểm tra kích thước tệp và cung cấp thông báo thích hợp cho người dùng rằng kích thước tệp sẽ tăng giới hạn. if (FileUpload.Lenght> TotalBytes của giới hạn của bạn (1024 * 2 (MB))) {} –

2

Thật vậy, thử sức sẽ không giúp bạn. Nhưng đây là một cách giải quyết: bạn có thể xử lý lỗi trong phương thức Global.asax Application_Error của mình.

Ví dụ:

void Application_Error(object sender, EventArgs e) 
{ 
    // manage the possible 'Maximum Length Exceeded' exception 
    HttpContext context = ((HttpApplication)sender).Context; 
    /* test the url so that only the upload page leads to my-upload-error-message.aspx in case of problem */ 
    if (context.Request.Url.PathAndQuery.Contains("mypage")) 
     Response.Redirect("/my-upload-error-message.aspx"); 

} 

Tất nhiên, lưu ý rằng nếu bất kỳ loại khác của lỗi xảy ra trên trang "mypage" của bạn, bạn sẽ được chuyển đến các /my-upload-error-message.aspx, bất kể chuyện gì đã xảy ra.

+0

Đó là một ý nghĩ tốt, thật không may, nó hoạt động. Mã Application_Error không bao giờ được tiếp cận. Tôi vẫn nhận được Internet Explorer không thể hiển thị lỗi trang web. –

+0

bạn đã thử đặt điểm ngắt trong Application_error chưa? cũng: có thể có một lỗi trong bản thân application_error? –

+0

Cũng có thể thử chạy dự án của bạn trên một trang web iis thực, và không phải với máy chủ cục bộ Visual Studio của bạn. –

3
  1. Tại máy khách, Flash và/hoặc ActiveX và/hoặc Java và/hoặc tệp HTML5 API là cách duy nhất để kiểm tra kích thước tệp và ngăn gửi. Sử dụng trình bao bọc/trình cắm thêm như Uploadify, bạn không phải cuộn của riêng mình và bạn nhận được giải pháp trình duyệt chéo.

  2. Trên máy chủ, trong global.asax, đặt này:

    public const string MAXFILESIZEERR = "maxFileSizeErr"; 
    
    public int MaxRequestLengthInMB 
    { 
        get 
        { 
         string key = "MaxRequestLengthInMB"; 
    
         double maxRequestLengthInKB = 4096; /// This is IIS' default setting 
    
         if (Application.AllKeys.Any(k => k == key) == false) 
         { 
          var section = ConfigurationManager.GetSection("system.web/httpRuntime") as HttpRuntimeSection; 
          if (section != null) 
           maxRequestLengthInKB = section.MaxRequestLength; 
    
          Application.Lock(); 
          Application.Add(key, maxRequestLengthInKB); 
          Application.UnLock(); 
         } 
         else 
          maxRequestLengthInKB = (double)Application[key]; 
    
         return Convert.ToInt32(Math.Round(maxRequestLengthInKB/1024)); 
        } 
    } 
    
    void Application_BeginRequest(object sender, EventArgs e) 
    { 
        HandleMaxRequestExceeded(((HttpApplication)sender).Context); 
    } 
    
    void HandleMaxRequestExceeded(HttpContext context) 
    { 
        /// Skip non ASPX requests. 
        if (context.Request.Path.ToLowerInvariant().IndexOf(".aspx") < 0 && !context.Request.Path.EndsWith("/")) 
         return; 
    
        /// Convert folder requests to default doc; 
        /// otherwise, IIS7 chokes on the Server.Transfer. 
        if (context.Request.Path.EndsWith("/")) 
         context.RewritePath(Request.Path + "default.aspx"); 
    
        /// Deduct 100 Kb for page content; MaxRequestLengthInMB includes 
        /// page POST bytes, not just the file upload. 
        int maxRequestLength = MaxRequestLengthInMB * 1024 * 1024 - (100 * 1024); 
    
        if (context.Request.ContentLength > maxRequestLength) 
        { 
         /// Need to read all bytes from request, otherwise browser will think 
         /// tcp error occurred and display "uh oh" screen. 
         ReadRequestBody(context); 
    
         /// Set flag so page can tailor response. 
         context.Items.Add(MAXFILESIZEERR, true); 
    
         /// Transfer to original page. 
         /// If we don't Transfer (do nothing or Response.Redirect), request 
         /// will still throw "Maximum request limit exceeded" exception. 
         Server.Transfer(Request.Path); 
        } 
    } 
    
    void ReadRequestBody(HttpContext context) 
    { 
        var provider = (IServiceProvider)context; 
        var 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[512000]; 
          // 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); 
         } 
        } 
    } 
    

    Tạo một lớp BasePage rằng trang của bạn sẽ kế thừa và thêm mã này vào nó:

    public int MaxRequestLengthInMB 
    { 
        get 
        { 
         return (Context.ApplicationInstance as Global).MaxRequestLengthInMB; 
        } 
    } 
    
    protected override void OnInit(EventArgs e) 
    { 
        base.OnInit(e); 
    
        CheckMaxFileSizeErr(); 
    } 
    
    private void CheckMaxFileSizeErr() 
    { 
        string key = Global.MAXFILESIZEERR; 
        bool isMaxFileSizeErr = (bool)(Context.Items[key] ?? false); 
        if (isMaxFileSizeErr) 
        { 
         string script = String.Format("alert('Max file size exceeded. Uploads are limited to approximately {0} MB.');", MaxRequestLengthInMB); 
         ScriptManager.RegisterClientScriptBlock(this, this.GetType(), key, script, true); 
        } 
    } 
    

    Cuối cùng, trong web.config, bạn PHẢI đặt maxAllowedContentLength (tính bằng byte) lớn hơn maxRequestLength (tính bằng kB).

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

<system.webServer> 
    <security> 
    <requestFiltering> 
     <requestLimits maxAllowedContentLength="2000000000" /> 
    </requestFiltering> 
    </security> 
</system.webServer> 
+0

Cảm ơn vì điều này. Quản lý của tôi đã nói với tôi không theo đuổi giải quyết các vấn đề liên quan đến việc tải lên tệp. Tôi muốn theo đuổi điều này tại một số thời điểm, nhưng lịch trình của tôi không cho phép tôi xem xét nó vào lúc này. –

+0

+1: Bạn là người đàn ông! –

+0

Tôi sẽ thử giải pháp này! –

0

In your web.config, set the max allowed content lenght higher than what you want to accept:

<system.webServer> 
    <security> 
    <requestFiltering> 
     <requestLimits maxAllowedContentLength="2000000000" /> 
    </requestFiltering> 
    </security> 
</system.webServer> 

Then, in global.asax, use Application_BeginRequest để thiết lập giới hạn của riêng bạn:

private const int MyMaxContentLength = 10000; //Wathever you want to accept as max file. 
    protected void Application_BeginRequest(object sender, EventArgs e) 
    { 
    if ( Request.HttpMethod == "POST" 
     && Request.ContentLength > MyMaxContentLength) 
    { 
     Response.Redirect ("~/errorFileTooBig.aspx"); 
    } 
    } 
Các vấn đề liên quan