Использование Backload для загружаемых файлов в ASP.NET MVC

от автора

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

С Javascript’овыми аплоадерами все оказалось очень неплохо – вариантов весьма приличное количество, на все требования и вкусы. А вот с серверными компонентами для реализации бекенда ситуация оказалась несколько хуже. Большая часть решений, которые я нашел, представляла собой небольшие примеры хэндлеров, об которые для реального использования пришлось бы сточить не один напильник.

В итоге, для работы на клиенте был выбран неоднократно обсуждавшийся на хабре jQuery-File-Upload, благо для него есть и angularjs обертка (что было актуально), и, в его документации была обнаружена ссылка на ту реализацию бекенда, о которой я и хотел бы рассказать – Backload.

Backload представляет собой полноценную реализацию бекенда для нескольких js-плагинов для upload’а (включая jquery-file-upload). Проект постоянно развивается, имеет приличный набор настроек и возможностей и позволяет быстро поднять толково работающий механизм для приема загружаемых файлов.

Проект имеет несколько редакций – бесплатную (standart) и ряд платных. Но данная ложка дегтя компенсируется тем, что для большинства задач бесплатного варианта хватает с головой (мне хватило полностью).

Для начала работы достаточно установить пакет Backload из nuget’а или поставить его сразу с jquery-file-upload’ом.
Для самых простых целей – простой установки хватает, достаточно лишь указать для jquery-file-upload нужный URL:

var fileUoloadUrl = "/Backload/UploadHandler"; $('#fileupload').fileupload({ 	url: fileUploadUrl }); 

И все. Запросы будут обрабатываться встроенным обработчиком.

Для ситуаций, когда этого недостаточно и хочется настроить и кастомизировать процесс более детально – имеется возможность настроить поведение Backload’а с помощью правки конфигурационного файла (.config), либо же влезть в работу обработчика, обрабатывая его события.

Для этого надо создать свой контроллер, и указать jquery-file-upload’у его урл. После чего в своем контроллере создаем экземпляр FileUploadHandler, подписываемся на те из его событий, которые нам нужны и передаем ему обработку.

Пример контроллера с подпиской на события Backload'а

public class FileUploadController : Controller { 	public async Task<ActionResult> FileHandler() 	{ 		FileUploadHandler handler = new FileUploadHandler(Request, this); 		handler.IncomingRequestStarted += handler_IncomingRequestStarted;  		handler.AuthorizeRequestStarted += handler_AuthorizeRequestStarted; 		handler.AuthorizeRequestFinished += handler_AuthorizeRequestFinished;  		handler.GetFilesRequestStarted += handler_GetFilesRequestStarted; 		handler.GetFilesRequestFinished += handler_GetFilesRequestFinished; 		handler.GetFilesRequestException += handler_GetFilesRequestException;  		handler.StoreFileRequestStartedAsync += handler_StoreFileRequestStartedAsync  		handler.StoreFileRequestFinished += handler_StoreFileRequestFinished; 		handler.StoreFileRequestException += handler_StoreFileRequestException;  		handler.DeleteFilesRequestStarted += handler_DeleteFilesRequestStarted; 		handler.DeleteFilesRequestFinishedAsync += handler_DeleteFilesRequestFinishedAsync;  		handler.DeleteFilesRequestException += handler_DeleteFilesRequestException;  		handler.OutgoingResponseCreated += handler_OutgoingResponseCreated;  		handler.ProcessPipelineExceptionOccured += handler_ProcessPipelineExceptionOccured;   		ActionResult result = await handler.HandleRequestAsync(); 		return result; 	}  	/* обработка событий*/ } 

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

Простой пример

async Task handler_StoreFileRequestStartedAsync(object sender, StoreFileRequestEventArgs e) { 	var fileName = e.Param.FileStatusItem.FileName; 	if (fileName.Equals("some_bad_name.tmp", StringComparison.OrdinalIgnoreCase)) 	{ 		fileName = "some_good_name.tmp";  		e.Param.FileStatusItem.FileName = fileName; 		e.Param.FileStatusItem.UpdateStatus(true); 	} } 

Или, например, по завершении аплоада что-то сделать с файлом.

Еще один простой пример

void handler_StoreFileRequestFinished(object sender, StoreFileRequestEventArgs e) { 	var fileName = e.Param.FileStatusItem.FileName; 	var folder = e.Param.FileStatusItem.StorageInfo.FileDirectory;  	DoSomeOperations(folder, fileName); } 

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

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

ссылка на оригинал статьи http://habrahabr.ru/post/204878/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *