В данной статье будет рассмотрен пример загрузки файлов на Ваш сервер с использованием авторизации и сохранение записи о файле в БД.
Так же стоить отметить пример рассчитан на основе отдельно сервиса загрузки файлов и обработки. Все примеры ниже актуальны только для сервиса для интеграции в монолит Вам предстоит переработать несколько методов.
Скажем так местами код выглядит просто ужасно нагромождение if «ифок» просто зашкаливает и это только кусок примера, ниже иллюстрация:

Попробуем все это структурировать с помощью подхода pipeline. Создадим класс fileUploadPipeline.

public class fileUploadPipeline
{
}
В конструкторе наш класс будет принимать HttpRequestMessage с которым в дальнейшем мы будем работать.
public class fileUploadPipeline
{
private HttpRequestMessage request;
public fileUploadPipeline(HttpRequestMessage request)
{
this.request = request;
}
}
Добавляем в Наш класс метод валидации токена на стронем сервере и пишем внутри него бизнес эксепшены и логику проверки и получения токена из заголовка, если Вам не требуется проверка авторизации то этот метод в дальнейшем можно не вызывать.
/// <summary>
/// Проверка токена и получние информации о пользователе
/// </summary>
/// <returns></returns>
internal async System.Threading.Tasks.Task<fileUploadPipeline> ValidateUserAsync()
{
var headers = request.Headers;
if (!headers.Contains("Authorization")) throw new UnauthorizedAccessException("Ошибка доступа");
var bearer = headers.GetValues("Authorization").FirstOrDefault();
using(HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", bearer);
var response = await client.PostAsync(ConfigurationManager.AppSettings["apiUrl"] + "User/SecureValidateToken", null);
var responseString = await response.Content.ReadAsStringAsync();
answer = JsonConvert.DeserializeObject<AnswerValidateToken>(responseString);
if(answer.state) return this;
}
throw new UnauthorizedAccessException("Ошибка доступа");
}
Объект AnswerValidateToken содержит данные о пользователе

Пишем метод извлечения файлов из запроса
/// <summary>
/// Извлечение файлов из запроса
/// </summary>
/// <returns></returns>
internal fileUploadPipeline ExtractFiles()
{
foreach (string file in request.Files)
{
string extension = System.IO.Path.GetExtension(request.Files[file].FileName).ToLower();
if (availableFileExtensions.ContainsKey(extension))
{
string mimeType = MimeMapping.GetMimeMapping(System.IO.Path.GetExtension(request.Files[file].FileName));
Models.AppFile.TypeFile typeFile = availableFileExtensions[extension];
var postedFile = request.Files[file];
var NewNameFile = Guid.NewGuid() + extension;
var filePath = root + NewNameFile;
postedFile.SaveAs(filePath);
}
}
return this;
}
И вот так прмерно у Вас должен выглядить финальный вариант pipeline загрузки файла от клиента через api микро сервиса. Сразу хочется оговориться это не финальный код Нашей разработки, это 1 из подходов к загрузке файлов используя ASP.NET MVC.
public class fileUploadPipeline
{
#region private variables
private HttpRequest request;
private AnswerValidateToken answer;
private string root = HttpContext.Current.Server.MapPath("~/Uploads/");
private Dictionary<string, Models.AppFile.TypeFile> availableFileExtensions = new Dictionary<string, Models.AppFile.TypeFile>()
{
{ ".mp4", MVideo },
};
List<Models.AppFile> files = new List<Models.AppFile>();
#endregion
/// <summary>
/// Базовый конструктор
/// </summary>
/// <param name="request"></param>
public fileUploadPipeline(HttpRequest request)
{
this.request = request;
}
/// <summary>
/// Проверка токена и получние информации о пользователе
/// </summary>
/// <returns></returns>
internal fileUploadPipeline ValidateUser()
{
return Task.Run(async () =>
{
var headers = request.Headers;
if (headers["Authorization"] == null) throw new UnauthorizedAccessException("Ошибка доступа");
var bearer = headers.GetValues("Authorization").FirstOrDefault();
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", bearer);
var response = await client.PostAsync(ConfigurationManager.AppSettings["apiUrl"] + "User/SecureValidateToken", null);
var responseString = await response.Content.ReadAsStringAsync();
answer = JsonConvert.DeserializeObject<AnswerValidateToken>(responseString);
if (answer.state) return this;
}
throw new UnauthorizedAccessException("Ошибка доступа");
}).Result;
}
/// <summary>
/// Метод проверки есть ли файлы в запросе
/// </summary>
/// <returns></returns>
internal fileUploadPipeline CheckFiles()
{
if (request.Files.Count > 0)
{
return this;
}
throw new NotImplementedException();
}
/// <summary>
/// Извлечение файлов из запроса
/// </summary>
/// <returns></returns>
internal fileUploadPipeline ExtractFiles()
{
foreach (string file in request.Files)
{
string extension = System.IO.Path.GetExtension(request.Files[file].FileName).ToLower();
if (availableFileExtensions.ContainsKey(extension))
{
string mimeType = MimeMapping.GetMimeMapping(System.IO.Path.GetExtension(request.Files[file].FileName));
Models.AppFile.TypeFile typeFile = availableFileExtensions[extension];
var postedFile = request.Files[file];
var NewNameFile = Guid.NewGuid() + extension;
var filePath = root + NewNameFile;
postedFile.SaveAs(filePath);
}
}
return this;
}
}
И вызвать этот pipeline в контроллере
public async System.Threading.Tasks.Task<IHttpActionResult> Post()
{
try
{
var uploadPipe = new Pipelines.fileUploadPipeline(HttpContext.Current.Request)
.CheckFiles()
.ValidateUser()
.ExtractFiles()
.isCheckTypeSet();
}
catch (UnauthorizedAccessException)
{
return Unauthorized();
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}