Pregunta

Estoy escribiendo una función de carga, y tiene problemas de captura "del Sistema.Web.HttpException:La máxima longitud de la solicitud superado" con archivos de mayor tamaño que el especificado el tamaño máximo en httpRuntimeen web.config (tamaño máximo conjunto de 5120).Estoy usando un simple <input> para el archivo.

El problema es que la excepción se produce antes de la carga del botón haga clic en el evento, y la excepción que sucede antes de que el código se ejecute.Entonces, ¿cómo puedo detectar y controlar la excepción?

EDITAR: La excepción es lanzada al instante, así que estoy bastante seguro de que no es un problema de tiempo de espera debido a la lentitud de las conexiones.

¿Fue útil?

Solución

No hay manera fácil de coger dicha excepción por desgracia. Lo que hago es o bien reemplazar el método OnError a nivel de página o la Application_Error en global.asax, a continuación, comprobar si fue un fracaso Max solicitud y, si es así, transferir a una página de error.

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

Es un truco, pero el siguiente código funciona para mí

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

Otros consejos

Como GateKiller dijo usted necesita para cambiar el maxRequestLength.Usted también puede necesitar para cambiar el executionTimeout en caso de que la velocidad de subida es muy lenta.Tenga en cuenta que usted no desea que cualquiera de estos parámetros a ser demasiado grande, de lo contrario va a estar abierto a los ataques de DOS.

El valor predeterminado para el executionTimeout es de 360 segundos o 6 minutos.

Usted puede cambiar el maxRequestLength y executionTimeout con el Elemento httpRuntime.

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

EDITAR:

Si desea manejar la excepción, independientemente, a continuación, como se ha dicho ya que usted necesitará para manejar en Global.asax.Aquí hay un enlace a un ejemplo de código.

Puede resolver este aumentando la longitud máxima de solicitud en su web.config:

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

El ejemplo anterior es para un límite de 100 MB.

Hola solución mencionada por Damien McGivern, Funciona en IIS6 única,

No funciona en IIS7 y ASP.NET servidor de desarrollo. Consigo página donde se presentan "404 -. Archivo o directorio no encontrado"

¿Alguna idea?

EDIT:

Lo tengo ... Esta solución todavía no funciona en ASP.NET servidor de desarrollo, pero me dio la razón por la que no estaba trabajando en IIS7 en mi caso.

La razón es IIS7 ha pedido un escaneo incorporado que impone una tapa de carga de archivos que por defecto es 30.000.000 bytes (que es ligeramente menor que 30 MB).

Y yo estaba tratando de subir el archivo de tamaño de 100 MB para probar la solución mencionada por Damien McGivern (con maxRequestLength = "10240" 10 MB es decir, en web.config). Ahora, si subo el archivo de tamaño> 10 MB y <30 MB entonces la página se redirige a la página de error especificado. Sin embargo, si el tamaño del archivo es> 30 MB entonces se muestra la página de error incorporada fea mostrando "404 -. Archivo o directorio no encontrado"

Por lo tanto, para evitar esto, usted tiene que aumentar al máximo. permitido longitud del contenido solicitud de su sitio web en IIS7. Eso se puede hacer usando los siguientes comandos,

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

He puesto el máximo. longitud del contenido a 200 MB.

Después de hacer este ajuste, la página se redirige succssfully a mi página de error cuando intento cargar un archivo de 100 MB

Consulte, http://weblogs.asp.net/jgalloway/archive/2008/01/08/large-file-uploads-in-asp-net.aspx para más detalles.

Si estás interesado en una validación del lado del cliente también por lo que se obtiene menos de la necesidad de lanzar excepciones que podría tratar de implementar la validación de tamaño de archivo del lado del cliente.

Nota: Esto sólo funciona en los navegadores que soportan 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>

Esta es una forma alternativa, que no implica ningún "hacks", pero requiere ASP.NET 4.0 o posterior:

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

Una forma de hacer esto es establecer el tamaño máximo en web.config como ya se ha indicado anteriormente, por ejemplo,

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

A continuación, cuando se controla el evento de carga, verificar el tamaño y si hay más de una cantidad específica, puede interceptar se por ejemplo.

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

En IIS 7 y más allá:

archivo web.config:

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

A continuación, puede comprobar en el código detrás, así:

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

Sólo asegúrese de que la [tamaño en bytes] en el web.config es mayor que el tamaño del archivo que desea cargar, entonces no obtendrá el error 404. A continuación, puede comprobar el tamaño del archivo de código subyacente mediante el ContentLength que sería mucho mejor

Como usted probablemente sabe, la longitud máxima de solicitud se configura en dos lugares.

  1. maxRequestLength - controlada a nivel aplicación ASP.NET
  2. maxAllowedContentLength - bajo <system.webServer>, controlada a nivel IIS

El primer caso está cubierto por otras respuestas a esta pregunta.

Para atrapar EL SEGUNDO que tiene que hacer esto en 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();
    }
}

Después de etiqueta

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

agregue la siguiente etiqueta

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

usted puede agregar la Url a la página de error...

Puede resolver esto aumentando el tiempo máximo de duración solicitud y ejecución en su web.config:

-Por favor aclarar el tiempo máximo de ejecución fuera rallador entonces 1200

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

¿Qué hay de captura que en el evento 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);
        }
    }

Se puede comprobar a través de:

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

                return;

            }
        }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top