0

I am building an application with .Net WebApi. I have an endpoint for uploading files and I have setup the web.config as follows:

<httpRuntime targetFramework="4.5" maxRequestLength="300000" />

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

Currently, if I upload a file that is larger than ~300Mb a 404.13 status code is returned. However, I would like to return a 400 instead. I believe the 404 is being thrown by IIS itself because no matter what I do in the code I can never catch the exception. I have tried the following already:

Implementing an ExceptionHandler: http://www.asp.net/web-api/overview/error-handling/web-api-global-error-handling

Implementing Application_Error: Catching "Maximum request length exceeded"

Implement Application_BeginRequest: http://geekswithblogs.net/sglima/archive/2011/09/20/how-to-handle-maximum-request-length-exceeded-exception.aspx

Surrounding the controller activator in a try catch: http://blog.greatrexpectations.com/2013/05/15/exception-handling-for-web-api-controller-constructors/

Replacing 404.13 error in web.config:

<httpErrors errorMode="Custom">
  <remove statusCode="404" subStatusCode="13" />            
  <error statusCode="404" subStatusCode="13" path="/errors/filesize" responseMode="Redirect" />   
</httpErrors>

Implementing a DelegatingHandler: Exception Handling ASP.NET MVC Web API

Nothing seems to work and I tried setting break points at the beginning of any of the methods stated above and it never enters any of them when the exception is thrown.

Community
  • 1
  • 1
GBreen12
  • 1,832
  • 2
  • 20
  • 38

1 Answers1

0

You can try this in Global.asax.cs:

protected void Application_BeginRequest(Object sender, EventArgs e)
{
    if (Request.ContentLength > N) // set the N to the maximum allowed value
    {
        Response.StatusCode = 400;
        Response.End();
    }
}

Please note that ContentLength refers to the whole request body length. If this doesn't work, try using Request.Headers["Content-Length"] instead of Request.ContentLength (which might calculate the length after the request has fully arrived on the server). Also, you can force your consumers to send the Content-Length header for some requests, for example:

// your condition might be based on the request URI if you don't 
// use a different Content-Type for your file upload method in web api
if (Request.Headers["Content-Type"] != null &&
    Request.Headers["Content-Type"].StartsWith("multipart/form-data;"))
{
    if(Request.Headers["Content-Length"] == null)
    {
        Response.StatusCode = 400;
        Response.End();
    }
}
Cosmin Vană
  • 1,562
  • 12
  • 28
  • I have already tried implementing Application_BeginRequest and the breakpoint in that method never gets hit when I try to upload a file too large – GBreen12 Jan 16 '15 at 18:52
  • Yes... I noticed that happens. I think it used to work in the past, but some things changed with IIS since then. I'll come back if I find a solution. It's quite strange that BeginRequest does not get called before the request is fully uploaded when it's size exceeds the one in Web.Config, but gets called for large files below that limit even before the upload to the server it's complete. – Cosmin Vană Jan 17 '15 at 07:21
  • A native HTTP module would work, but I think you'd rather not go into that (I'd also avoid creating a IIS version specific solution in C++) – Cosmin Vană Jan 17 '15 at 07:24