I have an aspx page using standard
FileUpload control. When I tried to upload a file bigger than 4MB the page was not displayed or the following error message appeared: "
Maximum request length exceeded". This is caused by maximal allowed size of request accepted by the server. Since the uploaded file is sent in request's body the whole request is even bigger than the file itself.
I've seen some solutions using
Application_Error
handler defined in Global.asax. This approach is quite straightforward and seems to be a way to go but unfortunately it didn't work for me - the page was still not displayed and the error was not handled.
Solution:First, set the size of request accepted by the server to maximum (1GB) in web.config. Then, define a custom
HttpModule that would check request's length (also in web.config):
<system.web>
<httpRuntime maxRequestLength="102400" />
<httpModules>
<add name="RequestLengthCheck"
type="MyNamespace.RequestCheckModule, MyLibraryName" />
</httpModules>
</system.web>
Now you have to implement the HttpModule that would check request's size and redirect to an error page if it's too big:
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
namespace MyNamespace
{
public class RequestCheckModule : IHttpModule
{
public void Init(HttpApplication app)
{
app.BeginRequest += new EventHandler(app_BeginRequest);
}
void app_BeginRequest(object sender, EventArgs e)
{
HttpContext context = (HttpApplication)sender).Context;
if (context.Request.ContentLength > 4096000)
{
IServiceProvider prov = (IServiceProvider)context;
HttpWorkerRequest wr =
(HttpWorkerRequest)prov.GetService(typeof(HttpWorkerRequest));
// Check if body contains data
if (wr.HasEntityBody())
{
// get the total body length
int reqLength = wr.GetTotalEntityBodyLength();
// Get the initial bytes loaded
int initBytes = wr.GetPreloadedEntityBody().Length;
if (!wr.IsEntireEntityBodyIsPreloaded())
{
byte[] buffer = new byte[512000];
// Set the received bytes to initial
// byted before start reading
int recBytes = initialBytes;
while (reqLength - recBytes >= initBytes)
{
// Read another set of bytes
initBytes = wr.ReadEntityBody(buffer, buffer.Length);
// Update the received bytes
recBytes += initBytes;
}
wr.ReadEntityBody(buffer, reqLength-recBytes);
}
}
// Redirect the user to an error page.
context.Response.Redirect("Error.aspx");
}
}
public void Dispose()
{
}
}
}
I've found this piece of code
here. It works perfect. The only thing I don't understand is why the whole request needs to be read for this to work? I've tried to make the redirection right after
wr.GetTotalEntityBodyLength();
but it didn't work. Anybody knows why?