I'm trying to create an HttpModule for my MVC application that will intercept a file upload request.
The goal is to catch the request before it's sent in order to check the content length of the request.
If the content length is larger than what is allowed, it should cancel that request and send an empty string as the response.
When a user clicks to upload a document, an ajax call is made to the UploadSignedDocument action:
[NoCache, HttpPost, ValidateAntiForgeryToken]
public string UploadSignedDocument(int orderid, HttpPostedFileBase fileUpload)
{
try
{
var fileinfo = new FileInfo(fileUpload.FileName);
var newFileName = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss_") + fileinfo.Name;
var docPath = Path.Combine(Server.MapPath("~/Uploads/"), newFileName);
fileUpload.SaveAs(docPath);
return newFileName;
}
catch
{
return "";
}
}
Which is intercepted by the following HttpModule:
public class UploadedFileSizeScreeningModule : IHttpModule
{
public void Init(HttpApplication application)
{
application.EndRequest += ValidateUploadRequest;
}
public void Dispose()
{
}
private static void ValidateUploadRequest(object source, EventArgs e)
{
HttpApplication context = source as HttpApplication;
if (context.Request.HttpMethod.ToUpperInvariant() != "POST" ||
!context.Request.Path.Contains("OrderQueue/UploadSignedDocument"))
{
return;
}
var requestLengthInMB = context.Request.ContentLength / 1024 / 1024;
if (requestLengthInMB > Settings.Default.MaxFileSizeInMB)
{
// TODO: Return new response (empty string)
}
}
}
How do I return an empty string back to the caller from the HttpHandler?
context.Response
itself to return the ajax response. Just write in there the empty string.HttpApplication.EndRequest
. That's where you may actually change (or even replace) the HTTP response.HttpApplication.PreSendRequestHeaders
event:You can use the PreSendRequestHeaders and PreSendRequestContext events with native IIS modules, but do not use them with managed modules that implement IHttpModule. Setting these properties can cause issues with asynchronous requests.
From What not to do in ASP.NET, and what to do instead.
Edit
Maybe something like this?
public class UploadedFileSizeScreeningModule : IHttpModule
{
public void Init(HttpApplication application)
{
application.EndRequest += ValidateUploadRequest;
}
public void Dispose()
{}
private static void ValidateUploadRequest(object source, EventArgs e)
{
HttpApplication context = source as HttpApplication;
if (context.Request.HttpMethod.ToUpperInvariant() != "POST" ||
!context.Request.Path.Contains("OrderQueue/UploadSignedDocument"))
{
return;
}
var requestLengthInMB = context.Request.ContentLength / 1024 / 1024;
if (requestLengthInMB > Settings.Default.MaxFileSizeInMB)
{
context.Response.Clear();
context.Response.Write(string.Empty);
context.Response.End();
}
}
}