File () или PhysicalFile () возвращают класс FileResult
, который просто делегирует обработку службе исполнителя.PhysicalFileResult
ExecuteResultAsync вызовы метода:
var executor = context.HttpContext.RequestServices
.GetRequiredService<IActionResultExecutor<PhysicalFileResult>>();
return executor.ExecuteAsync(context, this);
Все остальные классы, основанные на FileResult, работают аналогичным образом.
Класс PhysicalFileResultExecutor по существу записывает содержимое файла в поток ответа.
Быстрое и грязное решение состоит в создании собственного класса на основе PhysicalFileResult
, который делегируетв PhysicalFileResultExecutor, но удаляет файл после его завершения:
public class TempPhysicalFileResult : PhysicalFileResult
{
public TempPhysicalFileResult(string fileName, string contentType)
: base(fileName, contentType) { }
public TempPhysicalFileResult(string fileName, MediaTypeHeaderValue contentType)
: base(fileName, contentType) { }
public override async Task ExecuteResultAsync(ActionContext context)
{
await base.ExecuteResultAsync(context);
File.Delete(FileName);
}
}
Вместо вызова PhysicalFile()
для создания PhysicalFileResult
вы можете создать и вернуть TempPhysicalFileResult
, например:
return new TempPhysicalFileResult(file, "application/zip"){FileDownloadName=fileName};
Это то же самое, что PhysicalFile () делает:
[NonAction]
public virtual PhysicalFileResult PhysicalFile(
string physicalPath,
string contentType,
string fileDownloadName)
=> new PhysicalFileResult(physicalPath, contentType) { FileDownloadName = fileDownloadName };
Более сложным решением было бы создание собственного исполнителя, который позаботился бы, например, о сжатии, а также очистке файлов., оставляя код действия чистым от кода форматирования результата