2

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?

1 Answer 1

3
  1. You should be using the context.Response itself to return the ajax response. Just write in there the empty string.
  2. You should be subscribed to HttpApplication.EndRequest. That's where you may actually change (or even replace) the HTTP response.
  3. You should not be using the 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();            
        }
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your reply. I've changed it to use the EndRequest method but I'm not sure how to use the context.Request to write the response, can you shed some light on that? Currently it returns the html string of the 500 response from the server.
Sorry, I should've said context.Response. Made an edit, see if that code works (not sure, can't test it right now).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.