Сначала вы должны понять несколько вещей о 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>";
}
Это решение, конечно, имеет свои недостатки:
- Тем не менее, мы можем подвергнуться DoS-атаке с файлами размером 8 МБ, что мы сначала распознаем на уровне сервера, что уже очень поздно.
- Состояние пользовательской формы теряется в случае перенаправления из Global.asax, но это может быть преодолено с помощью небольшого количества кода.
- Пользовательский опыт довольно плох, из-за проверок на стороне сервера, и из-за нагрузки многих пользователей применение может стать медленным.
- Временно к серверу приходят файлы, размер которых превышает 8 МБ, но такие, которые управляются при выполнении Timeout
Возможные альтернативы:
- Используйте некоторую технологию флэш-памяти, чтобы проверить на стороне клиента размер файла
- Используйте некоторые потоковые приемы, чтобы передавать куски в небольших пакетах, и в тот момент, когда заданный порог будет достигнут, генерировать собственное исключение и обрабатывать его.
соответствующее чтение: Отправка файла в чанках в HttpHandler