التقاط رسالة "تم تجاوز الحد الأقصى لطول الطلب"

StackOverflow https://stackoverflow.com/questions/665453

  •  21-08-2019
  •  | 
  •  

سؤال

أنا أكتب دالة تحميل، وأواجه مشكلات في التقاط "System.Web.HttpException:تم تجاوز الحد الأقصى لطول الطلب" مع وجود ملفات أكبر من الحجم الأقصى المحدد httpRuntimeفي web.config (تم ضبط الحد الأقصى للحجم على 5120).أنا أستخدم بسيطة <input> للملف.

تكمن المشكلة في أنه يتم طرح الاستثناء قبل حدث النقر على زر التحميل، ويحدث الاستثناء قبل تشغيل الكود الخاص بي.فكيف يمكنني التقاط الاستثناء والتعامل معه؟

يحرر: يتم طرح الاستثناء على الفور، لذلك أنا متأكد من أنها ليست مشكلة انتهاء المهلة بسبب بطء الاتصالات.

هل كانت مفيدة؟

المحلول

لا توجد طريقة سهلة للقبض على هذا الاستثناء لسوء الحظ.ما أفعله هو إما تجاوز طريقة OnError على مستوى الصفحة أو Application_Error في global.asax، ثم التحقق مما إذا كان فشل الحد الأقصى للطلب، وإذا كان الأمر كذلك، قم بالتحويل إلى صفحة خطأ.

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

إنه اختراق ولكن الكود أدناه يعمل بالنسبة لي

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

نصائح أخرى

كما قال GateKiller فأنت بحاجة إلى تغيير maxRequestLength.قد تحتاج أيضًا إلى تغيير مهلة التنفيذ في حالة أن سرعة التحميل بطيئة جدًا.لاحظ أنك لا تريد أن يكون أي من هذه الإعدادات كبيرًا جدًا وإلا فسوف تكون عرضة لهجمات DOS.

الافتراضي لمهلة التنفيذ هو 360 ثانية أو 6 دقائق.

يمكنك تغيير maxRequestLength وExecutiveTimeout باستخدام الملف عنصر وقت تشغيل http.

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

يحرر:

إذا كنت تريد التعامل مع الاستثناء بغض النظر عن ذلك، كما ذكرنا سابقًا، فستحتاج إلى التعامل معه في Global.asax.هنا رابط ل مثال التعليمات البرمجية.

يمكنك حل هذه المشكلة عن طريق زيادة الحد الأقصى لطول الطلب في web.config الخاص بك:

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

المثال أعلاه هو بحد أقصى 100 ميجابايت.

مرحبا الحل الذي ذكره داميان ماكجيرن ، يعمل على IIS6 فقط ،

لا يعمل على IIS7 وASP.NET Development Server.أحصل على صفحة تعرض "404 - لم يتم العثور على الملف أو الدليل".

أيه أفكار؟

يحرر:

فهمتها...لا يزال هذا الحل لا يعمل على ASP.NET Development Server، ولكنني حصلت على سبب عدم عمله على IIS7 في حالتي.

السبب هو أن IIS7 يحتوي على فحص طلب مضمن يفرض حدًا أقصى لملف التحميل والذي يبلغ حجمه الافتراضي 30000000 بايت (وهو أقل قليلاً من 30 ميجابايت).

وكنت أحاول تحميل ملف بحجم 100 ميجابايت لاختبار الحل الذي ذكره داميان ماكجيفيرن (مع maxRequestLength = "10240" أي.10 ميغابايت في web.config).الآن، إذا قمت بتحميل ملف بحجم > 10 ميغابايت و< 30 ميغابايت، فسيتم إعادة توجيه الصفحة إلى صفحة الخطأ المحددة.ولكن إذا كان حجم الملف أكبر من 30 ميجابايت، فستظهر صفحة الخطأ المضمنة القبيحة التي تعرض "404 - لم يتم العثور على الملف أو الدليل".

لذا، لتجنب ذلك، عليك زيادة الحد الأقصى.طول محتوى الطلب المسموح به لموقع الويب الخاص بك في IIS7.ويمكن القيام بذلك باستخدام الأمر التالي،

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

لقد قمت بتعيين الحد الأقصى.طول المحتوى إلى 200 ميجابايت.

بعد القيام بهذا الإعداد، تتم إعادة توجيه الصفحة بنجاح إلى صفحة الخطأ الخاصة بي عندما أحاول تحميل ملف بحجم 100 ميجابايت

يشير إلى، http://weblogs.asp.net/jgalloway/archive/2008/01/08/large-file-uploads-in-asp-net.aspx لمزيد من التفاصيل.

إذا كنت تريد التحقق من جانب العميل أيضًا حتى لا تحتاج إلى طرح استثناءات، فيمكنك محاولة تنفيذ التحقق من صحة حجم الملف من جانب العميل.

ملحوظة:يعمل هذا فقط في المتصفحات التي تدعم HTML5.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>

إليك طريقة بديلة، لا تتضمن أي "اختراقات"، ولكنها تتطلب ASP.NET 4.0 أو أحدث:

//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
    }
}

إحدى الطرق للقيام بذلك هي تعيين الحد الأقصى للحجم في web.config كما سبق ذكره أعلاه، على سبيل المثال.

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

ثم عند التعامل مع حدث التحميل ، تحقق من الحجم وإذا كان أكثر من كمية محددة ، يمكنك فخه على سبيل المثال

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

في IIS 7 وما بعده:

ملف web.config:

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

يمكنك بعد ذلك التحقق من الكود الموجود خلفك، كما يلي:

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

فقط تأكد من أن [الحجم بالبايت] في web.config أكبر من حجم الملف الذي ترغب في تحميله، وبالتالي لن تحصل على الخطأ 404.يمكنك بعد ذلك التحقق من حجم الملف في الكود باستخدام ContentLength والذي سيكون أفضل بكثير

كما تعلم على الأرجح، تم تكوين الحد الأقصى لطول الطلب اثنين أماكن.

  1. maxRequestLength - يتم التحكم فيه على مستوى تطبيق ASP.NET
  2. maxAllowedContentLength - تحت <system.webServer>, ، يتم التحكم فيها على مستوى IIS

الحالة الأولى تغطيها إجابات أخرى على هذا السؤال.

للإمساك الثاني تحتاج إلى القيام بذلك في global.asax:

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

بعد العلامة

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

أضف العلامة التالية

 <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 إلى صفحة الخطأ...

يمكنك حل هذه المشكلة عن طريق زيادة الحد الأقصى لطول الطلب ومدة التنفيذ في web.config:

-يرجى توضيح الحد الأقصى لوقت التنفيذ ثم 1200

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

ماذا عن اللحاق به في حدث EndRequest؟

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

ويمكن التحقق من ذلك عن طريق:

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

                return;

            }
        }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top