Поймать загрузку в большие файлы - PullRequest
3 голосов
/ 27 ноября 2009

Asp.Net имеет верхний предел для загрузки файлов. Я пытаюсь уловить эту ситуацию на стороне сервера. Согласно документации, которую я нашел, должна быть возможность переопределить Application_Error в Global.asax, но он не работает для меня. Второй вариант - переопределить OnError на принимающей странице, но это также не работает.

Кто-нибудь может показать какой-нибудь рабочий код о том, как отловить эту ошибку на стороне сервера?

Ответы [ 5 ]

2 голосов
/ 08 января 2010

Поместите в Golobal.asax.cs следующее:

void Application_Error(Object sender, EventArgs e)
        {
            HttpException ex = Server.GetLastError() as HttpException;
            if (ex != null)
            {
                if ((ex.GetHttpCode() == 500 || ex.GetHttpCode() == 400) && ex.ErrorCode == -2147467259)
                {
                    Server.ClearError();
                    Response.Redirect("~/MaximumFileError.aspx", false);
                }
            }
        }

Это сработало для меня, но я не уверен, работает ли оно во всех случаях.

1 голос
/ 23 декабря 2009

Uploadify - это загрузчик jquery и flash, который позволяет указать максимальный размер загружаемых файлов. Таким образом, вы можете предотвратить загрузку файла пользователем и не беспокоиться о его перехвате.

0 голосов
/ 28 февраля 2013

Сначала вы должны понять несколько вещей о maxRequestLength. Используя проверку на стороне сервера, вы не можете предсказать размер файла. Установка высокого значения увеличивает риск DoS Attack. Я установил в web.config maxRequestLength значение 8 МБ:

 <httpRuntime maxRequestLength="8192" executionTimeout="3600" />

Я проверяю свой код от формы, если загруженный пользователем файл не превышает половину значения, указанного в maxRequestLength, но эта проверка может никогда не произойти, если размер загруженного файла окажется больше, чем максимальный RequestLength, указанный в сети. .config, потому что будет сгенерировано исключение. Такое исключение должно быть уловлено на уровне Global.asax. Там я проверяю, содержит ли исключение слова, идентифицирующие нашу проблему, потому что System.Web.HttpUnhandledException может быть вызвано во многих других ситуациях! Хорошей подсказкой может быть проверка того, с какой страницы происходит исключение, чтобы быть уверенным, что мы имеем дело с определенной формой, что важно при перенаправлении пользователя обратно в форму.

void Application_Error(object sender, EventArgs e){  
Exception wyjatek = Server.GetLastError();
        if (wyjatek.InnerException != null && wyjatek.InnerException.Message.Contains("Maximum request length exceeded"))
        {
            Server.ClearError();
            Response.Redirect("FormWithFile.aspx?alert=Za-duzy-plik");
        }  
    }

Если я распознаю в Global.asax это исключение, я перенаправляю пользователя на страницу с предупреждением (указано в GET).

В моем коде позади страницы ASPX:

Сначала я извлекаю значение MaxRequestLength из web.config по этим строкам дерева и наполовину:

static System.Configuration.Configuration config = WebConfigurationManager.OpenWebConfiguration("~");
static HttpRuntimeSection section = config.GetSection("system.web/httpRuntime") as HttpRuntimeSection;
int maxFileSize = (section.MaxRequestLength/2)*1024; 

Затем в действии, связанном с кнопкой вставки, я действую следующим образом:

  protected void InsertButton_Click(object sender, EventArgs e)
        {
            if (((FileUpload)FormView1.FindControl("FileUpload1")).HasFile) // WHEN USER WANT TO UPLOAD FORM WITH FILE (its, optional)
            {
                HttpPostedFile file = (HttpPostedFile)(((FileUpload)FormView1.FindControl("FileUpload1")).PostedFile);
                int iFileSize = file.ContentLength;
                if ((file != null) && (file.ContentLength > 0))
                {
                   if (iFileSize > maxFileSize) // checking image SIZE!
                    { 
                        MessageForUser.Text = "<h1 class=error>Bad File! File is to big!</h1>";
                    }
                    else
                    {
                        byte[] plik = ((FileUpload)FormView1.FindControl("FileUpload1")).FileBytes;
              // HERE COMES CODE FOR INSERT OF FORM WITH FILE
                        MessageForUser.Text = "<h1>Insert was sucessfull</h2>";
                    }
                }
            }
            else
            {
              // HERE COMES CODE FOR INSERT OF FORM WITHOUT FILE
                MessageForUser.Text = "<h1>Insert was sucessfull</h2>";
        }
    }

В Page_Load я также определяю, как восстановить связь, предоставляемую GET из Global.asax, чтобы сообщить пользователю, что произошло.

 if (Request.QueryString["alert"]!=null)
            {
                string temp =  Request.QueryString["alert"].Replace('-',' ');
                MessageForUser.Visible = true;
                MessageForUser.Text = "<h1 class=error>ERROR: " + temp + "</h1>";
            }   

Это решение, конечно, имеет свои недостатки:

  1. Тем не менее, мы можем подвергнуться DoS-атаке с файлами размером 8 МБ, что мы сначала распознаем на уровне сервера, что уже очень поздно.
  2. Состояние пользовательской формы теряется в случае перенаправления из Global.asax, но это может быть преодолено с помощью небольшого количества кода.
  3. Пользовательский опыт довольно плох, из-за проверок на стороне сервера, и из-за нагрузки многих пользователей применение может стать медленным.
  4. Временно к серверу приходят файлы, размер которых превышает 8 МБ, но такие, которые управляются при выполнении Timeout

Возможные альтернативы:

  1. Используйте некоторую технологию флэш-памяти, чтобы проверить на стороне клиента размер файла
  2. Используйте некоторые потоковые приемы, чтобы передавать куски в небольших пакетах, и в тот момент, когда заданный порог будет достигнут, генерировать собственное исключение и обрабатывать его. соответствующее чтение: Отправка файла в чанках в HttpHandler
0 голосов
/ 27 ноября 2009

"Кто-нибудь может показать какой-нибудь рабочий код на как отловить эту ошибку на сервере сторона? "

Нет. Невозможно использовать код для перехвата этой ошибки, так как это происходит до запуска любого кода.

Насколько я нашел, вы даже не можете указать альтернативную страницу ошибки для этой ошибки, веб-сервер просто отказывается принять запрос, когда он слишком велик.

0 голосов
/ 27 ноября 2009

Вместо того, чтобы поймать ошибку, не можете ли вы проверить размер файла по максимальному размеру, указанному в файле web.config? Вы можете использовать следующее, чтобы получить максимальный размер:

System.Configuration.Configuration config = WebConfigurationManager.OpenWebConfiguration("~");
HttpRuntimeSection section = config.GetSection("system.web/httpRuntime") as HttpRuntimeSection;
double maxFileSize = section.MaxRequestLength;
...