Нужна долгая обработка в контроллере ASP.NET Core без задержки на странице пользователя
подскажите пожалуйста, как правильно организовать архитектуру приложения ASP.Net Core. Задача: принимать большой файл от пользователя, обрабатывать его и возвращать пользователю обработанный файл. Проблема задачи в том, что обработка файла может занимать длительное время, пользователь же должен получать какой-то прогресс выполнения без зависания страницы. А также, WebServer может быть перезагружен, но результат все равно должен вернуться. Вопрос в основном об организации правильной структуры выполнения данной задачи.
- Думал об использовании sginalR, но в документации написано, что нельзя передавать большие файлы, signalR только для обмена небольшими сообщениями.
Ответы (1 шт):
Если вас не пугает фреймворк Blazor, то решение примерно такой же задачи, я встречал в курсе по Blazor, только там требовалось провести загрузку изображений из браузера, на сервер. При этом в процессе загрузки, нужно было также, настроить анимацию на странице. И это уже половина решения вашей задачи.
Первый этап. Настроим вывод по условию, анимации загрузки на странице, и для этого, в блоке с кодом, можно добавить, вспомогательное логическое свойство, что то типа private bool IsLoading, и в основном блоке div, можно добавить условие @if(IsLoadin) {}, далее внутри этой ветки можно добавить вывод блока с анимацией, что то типа <div <img src=/images/loading.gif> . в ветке else, будет отрисовка основного контента страницы.
Второй этап, это создание класса с сервисом загрузки файлов из потока, и добавление такого сервиса в контейнер зависимостей.
Третий этап это создание блока на странице со специальным визуальным компонентом:
<div ><InputFile OnChange="..."></InputFile></div>
Четвертый этап, создание метода, в блоке с кодом на странице Blazor, который будет вызван в этом OnChange, можно назвать его например UpImage. Далее пропишем сам метод:
private async Task UpImage() { }
В теле метода установим сразу IsLoading=true .
Далее добавим try {} catch(Exception e)
При этом для события OnChange, будет доступен специальный объект типа InputFileChangeEventArgs, добавим ссылку на него как входящий аргумент для метода, назовем его например просто e.
Далее в блоке try, в условии if проверим что хотя бы один файл был загружен из браузера, для этого запишем e.GetMultipleFiles().Count>0 .
Далее в foreach (var file in e.GetMultipleFiles()), можно извлечь название исходного файла, с помощью System.IO.FileInfo fileinfo = new System.IO.FileInfo.Name .
Пятый этап, это вызов сервиса для загрузки файла на сервер, и получение актуальной ссылки на место хранения такого файла на сервере.
Это может выглядеть примерно так: UserFile.LocalPath= await _fileUpload.UploadFile(file). В данном случае UserFile, это объект описывающий файл пользователя в системе, LocalPath это место его хранения на сервере, _fileUpload это экземпляр внедренного сервиса. UploadFile, это метод из стороннего сервиса для загрузки объектов из браузера, специального типа IBrowseFile, в данном примере это объект file.
Шестой этап. После успешной загрузки файла, ниже, можно добавить изменение логического состояния загрузки изменив значение IsLoading на false. Что позволит прекратить вывод анимации загрузки и будет отрсована страница, с ее новым состоянием.