Похоже, это вообще не имеет ничего общего с MVC. Это должен быть ваш компонент/код, конвертирующий PDF, который создает временный файл. Попробуйте удалить любую логику написания ответа или просто выполните отладку и остановите ее после вызова ConvertPdfToStream()
, и я почти уверен, что вы все равно увидите уже созданный файл.
Но гораздо лучше было бы переписать свой код, чтобы он лучше работал с архитектурой MVC. Теперь вы: 1. Явно задаете данные ответа 2. Сбрасываете поток ответов, закрываете ответ 3. И по-прежнему возвращаете новый объект Content("") для обработки подпрограммой MVC. Это странно и довольно непредсказуемо. В нашем проекте WebApi (почти так же, как MVC) мы используем что-то подобное для отправки файлов (упрощенное и модифицированное, чтобы почти не соответствовать вашему образцу):
/// <summary>
/// Custom <see cref="IHttpActionResult"/> that sends files using <see cref="StreamContent"/>
/// </summary>
public class FileResult : IHttpActionResult
{
ILogger Log = LogManager.GetLogger();
/// <summary>
/// Write buffer size. We use it for our internal services so 8MB buffer size - is the size tested and approved to be fine for our 1Gbps LAN transfers ;) you might want to change it
/// </summary>
private const int BUFFER_SIZE = 8388608;
/// <summary>
/// Initializer
/// </summary>
/// <param name="data">File data</param>
public FileResult(byte[] data)
{
Data = data;
}
/// <summary>
/// File data
/// </summary>
public byte[] Data
{ get; private set; }
/// <inheritdoc cref="IHttpActionResult.ExecuteAsync(CancellationToken)"/>
public async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var response = new HttpResponseMessage();
response.Content = new PushStreamContent(async (responseStream, content, context) =>
{
using (var source = new MemoryStream(Data))
{
try
{
if (source != null)
await source.CopyToAsync(responseStream, BUFFER_SIZE, cancellationToken);
}
catch (Exception e)
{
if (cancellationToken.IsCancellationRequested)
Log.Info("Data stream read operation aborted by client.");
else
{
Log.Warn(e);
throw;
}
}
responseStream.Close();
}
},
new MediaTypeHeaderValue("application/pdf"));
response.Content.Headers.ContentLength = Data.Length;
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "file.pdf",
Size = Data.Length,
};
return response;
}
}
а затем используйте его в своем контроллере следующим образом:
public IHttpActionResult LoadPdfStream(string url)
{
// this gets me the memory stream from the PDF file
MemoryStream memBuffer = _pdfViewerLogic.ConvertPdfToStream(url);
byte[] bytes = memBuffer.GetBuffer();
return new FileResult(bytes);
}
Таким образом, вам не нужно заботиться о сбросе ответа и вручную принудительно завершать запрос. Также этот код потоковой передачи вызывается только в том случае, если клиент действительно ждет его и хорошо отменяется при закрытии/запросе прерывания клиентского потока.
person
justmara
schedule
28.08.2015
Content-Disposition
? - person Eser   schedule 28.08.2015