Нет типа PushStreamContext
, встроенного в ASP.NET Core.Однако вы можете создать свой собственный FileCallbackResult
, который делает то же самое.Этот пример кода должен сделать это:
public class FileCallbackResult : FileResult
{
private Func<Stream, ActionContext, Task> _callback;
public FileCallbackResult(MediaTypeHeaderValue contentType, Func<Stream, ActionContext, Task> callback)
: base(contentType?.ToString())
{
if (callback == null)
throw new ArgumentNullException(nameof(callback));
_callback = callback;
}
public override Task ExecuteResultAsync(ActionContext context)
{
if (context == null)
throw new ArgumentNullException(nameof(context));
var executor = new FileCallbackResultExecutor(context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>());
return executor.ExecuteAsync(context, this);
}
private sealed class FileCallbackResultExecutor : FileResultExecutorBase
{
public FileCallbackResultExecutor(ILoggerFactory loggerFactory)
: base(CreateLogger<FileCallbackResultExecutor>(loggerFactory))
{
}
public Task ExecuteAsync(ActionContext context, FileCallbackResult result)
{
SetHeadersAndLog(context, result, null);
return result._callback(context.HttpContext.Response.Body, context);
}
}
}
Использование:
[HttpGet("csv")]
public IActionResult GetCSV(long id)
{
return new FileCallbackResult(new MediaTypeHeaderValue("text/csv"), async (outputStream, _) =>
{
var data = await GetData(id);
var records = _csvGenerator.GenerateRecords(data);
var writer = new StreamWriter(outputStream);
var csv = new CsvWriter(writer);
csv.WriteRecords(stream, records);
await writer.FlushAsync();
})
{
FileDownloadName = "results.csv"
};
}
Имейте в виду, что FileCallbackResult
имеет те же ограничения, что и PushStreamContext
:если в обратном вызове возникает ошибка , веб-сервер не может сообщить клиенту об этой ошибке.Все, что вы можете сделать, это распространить исключение, которое заставит ASP.NET преждевременно закрыть соединение, поэтому клиенты получат сообщение об ошибке «соединение неожиданно закрыто» или «загрузка прервана».Это связано с тем, что HTTP отправляет код ошибки first в заголовке, прежде чем тело начнет потоковую передачу.