Использование HttpModule в MVC для возврата нового ответа, если длина содержимого запроса AJAX превышает максимально допустимую

Я пытаюсь создать HttpModule для моего приложения MVC, который будет перехватывать запрос на загрузку файла.

Цель состоит в том, чтобы перехватить запрос до его отправки, чтобы проверить длину содержимого запроса.

Если длина содержимого превышает допустимую, он должен отменить этот запрос и отправить пустую строку в качестве ответа.

Когда пользователь щелкает, чтобы загрузить документ, в действие UploadSignedDocument выполняется вызов ajax:

[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 "";
    }
}

Который перехватывается следующим 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)
        }
    }
}

Как вернуть пустую строку обратно вызывающей стороне из HttpHandler?

1 ответ

Решение
  1. Вы должны использовать context.Response сам вернуть ответ ajax. Просто напишите там пустую строку.
  2. Вы должны быть подписаны на HttpApplication.EndRequest, Вот где вы можете изменить (или даже заменить) HTTP-ответ.
  3. Вы не должны использовать HttpApplication.PreSendRequestHeaders событие:

Вы можете использовать события PreSendRequestHeaders и PreSendRequestContext с собственными модулями IIS, но не использовать их с управляемыми модулями, которые реализуют IHttpModule. Установка этих свойств может вызвать проблемы с асинхронными запросами.

Из чего не надо делать в ASP.NET, а что делать вместо.

редактировать

Может как то так?

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();            
        }
    }
}
Другие вопросы по тегам