"Maksimum istek uzunluğu aşıldı" yakalama


112

Bir yükleme işlevi yazıyorum ve httpRuntimeweb.config dosyasında belirtilen maksimum boyuttan daha büyük olan dosyalarla "System.Web.HttpException: Maksimum istek uzunluğu aşıldı" (maksimum boyut 5120 olarak ayarlandı) yakalama sorunları yaşıyorum . <input>Dosya için basit kullanıyorum .

Sorun, istisnanın yükleme düğmesinin tıklama olayından önce fırlatılması ve istisnanın kodum çalıştırılmadan önce gerçekleşmesidir. Öyleyse istisnayı nasıl yakalayıp üstesinden gelebilirim?

DÜZENLEME: İstisna anında atılır, bu yüzden yavaş bağlantılar nedeniyle bir zaman aşımı sorunu olmadığından oldukça eminim.


5
Bunu MVC ile deneyen oldu mu? İstisnayı doğru şekilde yakalayabiliyorum gibi görünüyor, ancak durduramıyorum: bir hata sayfası oluşturmaya çalıştığım her seferde aynı istisna ortaya çıkıyor.
Andy

Bu hata mesajı, denetleyiciye ulaşmadan önce IIS tarafından atılır. Kullanıcıya dosyanın maksimum yükleme sınırını (web yapılandırmanızda belirlenen) aştığını bildirmek için, dosya boyutunu bir onchange olayıyla JS aracılığıyla doğrudan doğrulayabilirsiniz. Örneğin <input type="file" id="upload" name="upload" onchange="showFileSize();" />Inside için showFileSize(), dosya boyutunuza bağlı olarak bir hata mesajı görüntüleyebilir var input = document.getElementById("upload"); var file = input.files[0];ve bir html etiketi ekleyebilirsiniz.
Alfred Wallace

Yanıtlar:


97

Ne yazık ki böyle bir istisnayı yakalamanın kolay bir yolu yok. Yaptığım şey, sayfa düzeyinde OnError yöntemini veya global.asax içindeki Application_Error değerini geçersiz kılmak, ardından bunun bir Maks İstek hatası olup olmadığını kontrol etmek ve eğer öyleyse, bir hata sayfasına aktarmak.

protected override void OnError(EventArgs e) .....


private void Application_Error(object sender, EventArgs e)
{
    if (GlobalHelper.IsMaxRequestExceededException(this.Server.GetLastError()))
    {
        this.Server.ClearError();
        this.Server.Transfer("~/error/UploadTooLarge.aspx");
    }
}

Bu bir hack ama aşağıdaki kod benim için çalışıyor

const int TimedOutExceptionCode = -2147467259;
public static bool IsMaxRequestExceededException(Exception e)
{
    // unhandled errors = caught at global.ascx level
    // http exception = caught at page level

    Exception main;
    var unhandled = e as HttpUnhandledException;

    if (unhandled != null && unhandled.ErrorCode == TimedOutExceptionCode)
    {
        main = unhandled.InnerException;
    }
    else
    {
        main = e;
    }


    var http = main as HttpException;

    if (http != null && http.ErrorCode == TimedOutExceptionCode)
    {
        // hack: no real method of identifying if the error is max request exceeded as 
        // it is treated as a timeout exception
        if (http.StackTrace.Contains("GetEntireRawContent"))
        {
            // MAX REQUEST HAS BEEN EXCEEDED
            return true;
        }
    }

    return false;
}

2
Teşekkürler. OnError çalışmadı, ancak Application_Error çalıştı. Aslında bunun için bir işleyicimiz var, ancak birisi bunu kodda kapatmıştı.
Marcus L

iki yıl önce bile, ama hala bunun şimdiye kadar iyi çalışıp çalışmadığını sormak istiyorum. 'GetEntireRawContent'in dize karşılaştırması iyi çalışıyor mu? Bunun bir zaman aşımı sorunu olduğunu sanmıyorum. Bu konuda beni bulutsuz bir yere işaret eden biri var mı?
Elaine

@Elaine evet, bu teknik hala ASP.Net 4.0 ile çalışıyor. Maksimum istek uzunluğundan daha büyük bir isteği karşıya yüklemeye çalışırsanız, ASP.Net, zaman aşımı koduyla bir HttpException oluşturur. Reflektör kullanarak System.Web.HttpRequest.GetEntireRawContent () 'e bir göz atın.
Damien McGivern

12
@ sam-rueby Yerelleştirme nedeniyle değişebilecek bir dize hata mesajını yanıtlamak istemedim.
Damien McGivern

4
.NET 4.0 ve sonrası için, maksimum istek boyutunun aşılıp aşılmadığını belirlemenin daha iyi bir yolu vardır. Bu koşulu HttpException için kontrol edebilirsiniz: httpException.WebEventCode == WebEventCodes.RuntimeErrorPostTooLarge- System.Web.Management.WebEventCodes kullanarak
mco

58

GateKiller'ın dediği gibi maxRequestLength değerini değiştirmeniz gerekir. Yükleme hızının çok yavaş olması durumunda da yürütme zaman aşımını değiştirmeniz gerekebilir. Bu ayarlardan hiçbirinin çok büyük olmasını istemediğinizi, aksi takdirde DOS saldırılarına açık olacağınızı unutmayın.

Yürütme Zaman Aşımı için varsayılan 360 saniye veya 6 dakikadır.

MaxRequestLength ve executionTimeout'u httpRuntime Öğesi ile değiştirebilirsiniz .

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <httpRuntime maxRequestLength="102400" executionTimeout="1200" />
    </system.web>
</configuration>

DÜZENLE:

İstisnayı ne olursa olsun ele almak istiyorsanız, daha önce belirtildiği gibi, Global.asax'ta halletmeniz gerekir. İşte bir kod örneğine bağlantı .


2
Cevabınız için teşekkürler, ancak GK'nın cevabına yaptığım yorumda da söylediğim gibi, bu gerçekten sorunumu çözmüyor. İstisna anında atıldığı için bu bir zaman aşımı sorunu da değildir. Daha net hale getirmek için soruyu düzenleyeceğim.
Marcus L

4
Kod örneği url'si kullanılamayan bir sayfaya işaret ediyor ... bunu herhangi biri düzeltebilir mi?
deostroll

20

Bunu, web.config'inizdeki maksimum istek uzunluğunu artırarak çözebilirsiniz:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <httpRuntime maxRequestLength="102400" />
    </system.web>
</configuration>

Yukarıdaki örnek 100Mb'lik bir limit içindir.


18
Evet ve hayır. Sınırı daha da zorlarsınız, ancak istisnayı gerçekten ele almaz. Birisi 101+ Mb yüklemeye çalışırsa yine aynı sorunu yaşarsınız. Sınırın gerçekten 5 Mb olması gerekiyor.
Marcus L

10

İstemci tarafı doğrulaması istiyorsanız, istisnaları atmaya daha az ihtiyaç duyuyorsanız, istemci tarafı dosya boyutu doğrulamasını uygulamaya çalışabilirsiniz.

Not: Bu, yalnızca HTML5'i destekleyen tarayıcılarda çalışır. http://www.html5rocks.com/en/tutorials/file/dndfiles/

<form id="FormID" action="post" name="FormID">
    <input id="target" name="target" class="target" type="file" />
</form>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>

<script type="text/javascript" language="javascript">

    $('.target').change(function () {

        if (typeof FileReader !== "undefined") {
            var size = document.getElementById('target').files[0].size;
            // check file size

            if (size > 100000) {

                $(this).val("");

            }
        }

    });

</script>


9

Damien McGivern'in bahsettiği merhaba çözüm, Yalnızca IIS6 üzerinde çalışıyor,

IIS7 ve ASP.NET Geliştirme Sunucusunda çalışmaz. "404 - Dosya veya dizin bulunamadı" şeklinde bir sayfa görüntülüyorum.

Herhangi bir fikir?

DÜZENLE:

Anladım ... Bu çözüm hala ASP.NET Geliştirme Sunucusunda çalışmıyor, ancak benim durumumda IIS7 üzerinde çalışmamasının nedenini anladım.

Bunun nedeni, IIS7'nin varsayılan olarak 30000000 bayta (30MB'den biraz daha az olan) yükleme dosyası sınırı uygulayan yerleşik bir istek taramasına sahip olmasıdır.

Ve Damien McGivern tarafından bahsedilen çözümü test etmek için 100 MB boyutunda dosya yüklemeye çalışıyordum (maxRequestLength = "10240" yani web.config'de 10MB ile). Şimdi, boyutu> 10MB ve <30 MB olan dosyayı yüklersem, sayfa belirtilen hata sayfasına yeniden yönlendirilir. Ancak dosya boyutu> 30MB ise, "404 - Dosya veya dizin bulunamadı" ifadesini görüntüleyen çirkin yerleşik hata sayfasını gösterir.

Yani, bundan kaçınmak için maks. IIS7'de web siteniz için izin verilen istek içeriği uzunluğu. Bu, aşağıdaki komut kullanılarak yapılabilir,

appcmd set config "SiteName" -section:requestFiltering -requestLimits.maxAllowedContentLength:209715200 -commitpath:apphost

Maks. Ayarladım. içerik uzunluğu 200 MB'a kadar.

Bu ayarı yaptıktan sonra, 100MB'lık bir dosya yüklemeye çalıştığımda sayfa başarıyla hata sayfama yönlendiriliyor

Daha fazla ayrıntı için http://weblogs.asp.net/jgalloway/archive/2008/01/08/large-file-uploads-in-asp-net.aspx adresine bakın .


Afedersiniz! Sorgumu Cevap olarak ekledim, mevcut gönderilere nasıl yorum ekleyeceğimi bilmiyorum.
Vinod T. Patil

1
Sadece daha fazla tekrara ihtiyacın var. gönderileri yorumlamak için. Mevcut temsilcinizle neler yapabileceğiniz / yapamayacağınız hakkında daha fazla ayrıntı için SSS bölümüne bakın.
slaphappy

7

Herhangi bir "hack" içermeyen, ancak ASP.NET 4.0 veya sonrasını gerektiren alternatif bir yol aşağıda verilmiştir:

//Global.asax
private void Application_Error(object sender, EventArgs e)
{
    var ex = Server.GetLastError();
    var httpException = ex as HttpException ?? ex.InnerException as HttpException;
    if(httpException == null) return;

    if(httpException.WebEventCode == WebEventCodes.RuntimeErrorPostTooLarge)
    {
        //handle the error
        Response.Write("Sorry, file is too big"); //show this message for instance
    }
}

4

Bunu yapmanın bir yolu, yukarıda belirtildiği gibi web.config dosyasında maksimum boyutu ayarlamaktır, örn.

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

daha sonra, yükleme olayını işlediğinizde, boyutu kontrol edin ve belirli bir miktarın üzerindeyse, onu yakalayabilirsiniz.

protected void btnUploadImage_OnClick(object sender, EventArgs e)
{
    if (fil.FileBytes.Length > 51200)
    {
         TextBoxMsg.Text = "file size must be less than 50KB";
    }
}

1
Bu çalışmıyor. Click olayı asla tetiklenmez. İstisna daha önce olur.
Lombas


3

IIS 7 ve sonrasında:

web.config dosyası:

<system.webServer>
  <security >
    <requestFiltering>
      <requestLimits maxAllowedContentLength="[Size In Bytes]" />
    </requestFiltering>
  </security>
</system.webServer>

Daha sonra arkadaki kodu kontrol edebilirsiniz, örneğin:

If FileUpload1.PostedFile.ContentLength > 2097152 Then ' (2097152 = 2 Mb)
  ' Exceeded the 2 Mb limit
  ' Do something
End If

Web.config dosyasındaki [Byte In Byte] 'ın yüklemek istediğiniz dosyanın boyutundan daha büyük olduğundan emin olun, sonra 404 hatasını almazsınız. Daha sonra, çok daha iyi olacak olan ContentLength kullanarak arkadaki koddaki dosya boyutunu kontrol edebilirsiniz.


2

Muhtemelen bildiğiniz gibi, maksimum istek uzunluğu İKİ yerde yapılandırılmıştır .

  1. maxRequestLength - ASP.NET uygulama düzeyinde denetlenir
  2. maxAllowedContentLength- altında <system.webServer>, IIS düzeyinde kontrol edilir

İlk durum, bu soruya verilen diğer cevaplarla kaplıdır.

İKİNCİ BİRİ yakalamak için bunu global.asax'ta yapmanız gerekir:

protected void Application_EndRequest(object sender, EventArgs e)
{
    //check for the "file is too big" exception if thrown at the IIS level
    if (Response.StatusCode == 404 && Response.SubStatusCode == 13)
    {
        Response.Write("Too big a file"); //just an example
        Response.End();
    }
}

1

Etiketten sonra

<security>
     <requestFiltering>
         <requestLimits maxAllowedContentLength="4500000" />
     </requestFiltering>
</security>

aşağıdaki etiketi ekle

 <httpErrors errorMode="Custom" existingResponse="Replace">
  <remove statusCode="404" subStatusCode="13" />
  <error statusCode="404" subStatusCode="13" prefixLanguageFilePath="" path="http://localhost/ErrorPage.aspx" responseMode="Redirect" />
</httpErrors>

URL'yi hata sayfasına ekleyebilirsiniz ...


0

Bunu, web.config dosyanızda maksimum istek uzunluğunu ve yürütme zaman aşımını artırarak çözebilirsiniz:

-Lütfen 1200'den sonra maksimum yürütme zaman aşımını netleştirin

<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <httpRuntime maxRequestLength="102400" executionTimeout="1200" /> </system.web> </configuration>

0

EndRequest etkinliğinde yakalamaya ne dersiniz?

protected void Application_EndRequest(object sender, EventArgs e)
    {
        HttpRequest request = HttpContext.Current.Request;
        HttpResponse response = HttpContext.Current.Response;
        if ((request.HttpMethod == "POST") &&
            (response.StatusCode == 404 && response.SubStatusCode == 13))
        {
            // Clear the response header but do not clear errors and
            // transfer back to requesting page to handle error
            response.ClearHeaders();
            HttpContext.Current.Server.Transfer(request.AppRelativeCurrentExecutionFilePath);
        }
    }

0

Şu yolla kontrol edilebilir:

        var httpException = ex as HttpException;
        if (httpException != null)
        {
            if (httpException.WebEventCode == System.Web.Management.WebEventCodes.RuntimeErrorPostTooLarge)
            {
                // Request too large

                return;

            }
        }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.