Pull to refresh

ASP.NET MVC 3 для начинающих: загрузка файлов на сервер

Reading time 3 min
Views 41K
image

В ходе обучения новым технологиям перед новичками часто возникают типовые задачи, которые не так просто решить. В цикле статей MVC3 для начинающих будут представлены решения таких задач.

Недавно, на конференции для разработчиков в Екатеринбурге, где я рассказывал про ASP.NET мне задали вопрос о том, как с помощью MVC3 и Razor организовать загрузку одного или нескольких файлов со стороны клиента на сервер. Вполне типовая задача, которая очень легко и элегантно решается в ASP.NET MVC3.

Ниже представлено полное решение с исходными кодами.

Разметка


Прежде всего сформируем разметку для страницы Index.cshtml контроллера Home:

<h2>Загрузка одного файла</h2>
<p>
@using (Html.BeginForm("", "home", FormMethod.Post, new {enctype="multipart/form-data"}))  {       
    <input type="file" name="fileUpload" /><br />      
    <input type="submit" name="Submit" id="SubmitSingle" value="Upload" />
}
</p>
<h2>Загрузка нескольких файлов</h2>
<p>
@using (Html.BeginForm("", "home", FormMethod.Post, new {enctype="multipart/form-data"}))  {      
    <input type="file" name="fileUpload[0]" /><br />      
    <input type="file" name="fileUpload[1]" /><br />      
    <input type="file" name="fileUpload[2]" /><br />      
    <input type="submit" name="Submit" id="SubmitMultiply" value="Upload" />
}
</p>

Здесь есть несколько важный моментов, которые необходимо разобрать:
  • для передачи больших файлов используется MIME-тип данных multipart/form-data;
  • при формировании формы с несколькими элементами загрузки файлов необходимо формировать имена элементов (атрибуты name) с индексаторами [№]. Это соглашение ASP.NET MVC3, которое позволяет автоматически получить массив элементов при работе с действиями контроллеров.
Как можно убедиться, код разметки тривиален.

Код действия в контроллере


Добавим контроллер Home действие Index с атрибутом Post и некоторыми параметрами:

[HttpPost]
public ActionResult Index(IEnumerable<HttpPostedFileBase> fileUpload)
{     
    foreach (var file in fileUpload)     
    {          
        if (file == null) continue;                        
        string path = AppDomain.CurrentDomain.BaseDirectory + "UploadedFiles/";
        string filename = Path.GetFileName(file.FileName);
        if (filename != null) file.SaveAs(Path.Combine(path, filename));
    }     

    return RedirectToAction("Index");
}

Здесь есть несколько важных моментов:
  • с помощью атрибута HttpPost мы определяем действие, которое будет обрабатывать только POST-запросы;
  • параметр IEnumerable<HttpPostedFileBase> fileUpload представляет перечисление файлов, которые были отправлены пользователем. Обратите внимание, что имя fileUpload совпадает со значением атрибута name элементов формы, в том числе, с теми которые содержат индексаторы [№]. Именно наличие индексаторов позволяет MVC3 автоматически присваивать в параметр перечисление.
Как можно убедиться еще раз, код действия не менее тривиален, чем код разметки.

Ограничение на размер запроса и web.config


В ASP.NET существует ограничение на размер запроса, который может быть передан на сервер. Это ограничение введено, в том числе, из соображений безопасности и легкого предотвращения атак на сервер путем формирования тяжелых запросов. Тем не менее, при создании функционала по загрузке на сервер файлов, особенно когда их несколько и они могут быть большого размера следует предварительно настроить параметр ограничения на нужное значение.

Параметр, который управляет максимальным размером запроса находится в web.config:

<system.web>
    <!--ограничение на размер запроса-->
    <httpRuntime maxRequestLength="10000" />

Параметр maxRequestLength указывает максимально допустимый размер в килобайтах, который может иметь запрос. Таким образом в коде выше установлен лимит на запрос в ~10 мегабайт. То есть пользователь может передать в одном запросе файл или файлы размером около десяти мегабайт. Учтите только, что запрос состоит не только из данных, но и некоторой обвязки, которая тоже формирует данные запроса. Эта обвязка имеет небольшой размер, но ее следует учитывать при расчете необходимого лимита на размер запроса.

Исходный код проекта


Вы можете загрузить исходный код работающего проекта для Visual Studio 2010 по этой ссылке.
Tags:
Hubs:
+28
Comments 24
Comments Comments 24

Articles