web-dev-qa-db-ja.com

asp:FileUpLoadコントロールを使用してファイルをアップロードするときにファイルが大きすぎます

asp:FileUpLoadを使用してasp.net c#プロジェクトにファイルをアップロードしています。ファイルサイズが許可されている最大値を超えない限り、これはすべて正常に機能します。最大値を超えたとき。 「Internet Explorer cannot display the webpage」というエラーが表示されます。問題は、try catchブロックがエラーをキャッチしないため、許容サイズを超えていることをuser a friendly messageに与えることができないことです。 Webの検索中にこの問題が発生しましたが、許容できる解決策が見つかりません。

私は他のコントロールを検討しますが、私の管理はおそらくサードパーティのコントロールを購入することにはなりません。

Ajacを示唆する回答に照らして、このコメントを追加する必要があります。私は数ヶ月前にajaxコントロールをロードしようとしました。 ajaxコントロールを使用するとすぐに、このコンパイルエラーが発生します。

エラー98タイプ 'System.Web.UI.ScriptControl'が、参照されていないアセンブリで定義されています。 Assembly'System.Web.Extensions、Version = 4.0.0.0、Culture = neutral、PublicKeyToken = 31bf3856ad364e35 'への参照を追加する必要があります。

'System.Web.Extensions'を追加しましたが、それを取り除くことができました。そこで、Ajaxを放棄し、他の手法を使用しました。

だから私はこの問題または完全に新しい解決策を解決する必要があります。

23
Bob Avallone

デフォルトのファイルサイズ制限は(4MB)ですが、アップロードページが存在するディレクトリにweb.configファイルをドロップすることで、ローカライズされた方法でデフォルトの制限を変更できます。そうすれば、サイト全体で大量のアップロードを許可する必要はありません(そうすると、特定の種類の攻撃にさらされることになります)。

Web.configの_<system.web>_セクションに設定するだけです。例えば以下の例では、最大長を_2GB_に設定しています。

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

maxRequestLengthはKB単位で設定され、2GB (2079152 KB's)まで設定できることに注意してください。実際には、_2GB_リクエストの長さを設定する必要はあまりありませんが、リクエストの長さを長く設定する場合は、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.)

詳細については、 httpRuntime Element(ASP.NET Settings Schema) をお読みください。

ここで、カスタムメッセージをユーザーに表示する場合、ファイルサイズが_100MB_より大きい場合。

あなたはそれを好きにすることができます。

_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.";
}
_
30
Muhammad Akhtar
  1. クライアントでは、Flashおよび/またはActiveXおよび/またはJavaおよび/またはHTML5Files APIが、ファイルサイズをテストして送信を防ぐ唯一の方法です。-のようなラッパー/プラグインを使用する ploadify 、自分でロールする必要はなく、クロスブラウザソリューションを利用できます。

  2. サーバー上で、global.asax、これを入れてください:

    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);
            }
        }
    }
    

    ページが継承するBasePageクラスを作成し、次のコードを追加します。

    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);
        }
    }
    

    最後に、web.config、あなた[〜#〜] must [〜#〜]maxAllowedContentLength(バイト単位)をmaxRequestLength(kB単位)より大きく設定します。

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

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

確かに、トライキャッチはあなたを助けません。ただし、回避策は次のとおりです。Global.asaxApplication_Errorメソッドでエラーを処理できます。

例:

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");

}

もちろん、「mypage」ページで他の種類のエラーが発生した場合は、何が起こったかに関係なく、/ my-upload-error-message.aspxにリダイレクトされることに注意してください。

2

Asp.netツールキットのアップロードコントロールを試すことができます。それは無料です!

http://www.asp.net/ajax/ajaxcontroltoolkit/samples/AsyncFileUpload/AsyncFileUpload.aspx

1
all2neat

Web.configで、許可する最大コンテンツ長を、受け入れたいコンテンツの長さよりも長く設定します。

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

次に、global.asaxで、Application_BeginRequestを使用して独自の制限を設定します。

  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");
     }
  }
0
Johnny5

これはセッションタイムアウトの問題のようです。セッション時間を増やしてから、再試行してください。 web.configファイルでセッションタイミングを設定できます

0
Ovais Khatri