How to catch ConfigurationErrorsException for viol

2019-01-23 06:56发布

问题:

I am limiting file size users can upload to the site from Web.config. As explained here, it should throw a ConfigurationErrorsException if size is not accepted. I tried to catch it from the action method or controller for upload requests but no luck. Connection is resetted and I can't get it to show an error page.

I tried catching it in BeginRequest event but no matter what I do the exception is unhandled. Here's the code:

protected void Application_BeginRequest(Object sender, EventArgs e)
{
    HttpContext context = ((HttpApplication)sender).Context;
    try
    {
        if (context.Request.ContentLength > maxRequestLength)
        {
            IServiceProvider provider = (IServiceProvider)context;
            HttpWorkerRequest 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[512];
                    // 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);
                }
            }
        }
    }
    catch(HttpException)
    {
        context.Response.Redirect(this.Request.Url.LocalPath + "?action=exception");
    }
}

But I still get this:

Maximum request length exceeded.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Web.HttpException: Maximum request length exceeded.

Source Error: 

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Update:

What method raises the exception anyway? If I read the request it raises exception If I don't read it at all, I get "101 Connection Reset" in browser. What can be done here?

回答1:

You cant catch error in action method becouse exception comes earlier, but you can catch it here

protected void Application_Error() {
     var lastError = Server.GetLastError();
     if(lastError !=null && lastError is HttpException && lastError.Message.Contains("exceed")) {
      Response.Redirect("~/errors/RequestLengthExceeded");
      }
    }   

Actualy when file size exceeds limits HttpException error arise.

There is also IIS limit on content - wich can't be catched in application. IIS 7 throws

HTTP Error 404.13 - Not Found The request filtering module is configured to deny a request that exceeds the request content length.

You can google it, there is a lot of information about this iis error.



回答2:

There is no way to do it right without a client-side help. You cannot determine if the request is too long unless you read all of it. If you read each request to the end, anyone come and keep your server busy. If you just look at content length and drop the request, other side is going to think there is a connection problem. It's nothing you can do with error handling, it's a shortcoming of HTTP.

You can use Flash or Javascript components to make it right because this thing can't fail nicely.



回答3:

I am not 100% on this, but I think it might help if you tried changing:

context.Response.Redirect(this.Request.Url.LocalPath + "?action=exception");

to

Server.Transfer(this.Request.Url.LocalPath + "?action=exception,false)

My thinking is that the the over-max-request-length Request is still being processed in the Redirect call but if you tell it to ditch the form data, it will become under the max request length and then it might behave differently.

No guarantees, but its easy to check.



回答4:

   catch (Exception ex)
   {
       if (ex is HttpException && (ex as HttpException).WebEventCode == 3004)
       {
            //-- you can now inform the client that file uploaded was too large.
       }
       else
           throw;
   }


回答5:

I have a similar issue in that I want to catch the 'Maximum request length exceeded' exception within the Application_Error handler and then do a Redirect.

(The difference is that I am writing a REST service with ASP.Net Web API and instead of redirecting to an error page, I wanted to redirect to an Error controller which would then return the appropriate response).

However, what I found was that when running the application through the ASP.Net Development Server, the Response.Redirect didn't seem to be working. Fiddler would state "ReadResponse() failed: The server did not return a response for this request."

My client (Advanced REST Client for Chrome) would simply show "0 NO RESPONSE".

If I then ran the application via a local copy of IIS on my development machine then the redirect would work correctly!

I'm not sure i can definitively say that Response.Redirect does not work on the ASP.Net Development Server but it certainly wasn't working in my situation.

So, I recommend trying to run your application through IIS instead of IIS Express or the Development Server and see if you get a different result.

See this link on how to Specify the Web Server for Web Projects in Visual Studio:

http://msdn.microsoft.com/en-us/library/ms178108(v=vs.100).aspx