В чем разница между четырьмя результатами файлов в ASP.NET MVC

ASP.NET имеет четыре различных типа результатов файла:

  • FileContentResult: отправляет содержимое двоичного файла в ответ.
  • FilePathResult: отправляет содержимое файла в ответ
  • FileResult: возвращает двоичный вывод для записи в ответ
  • FileStreamResult: отправляет двоичное содержимое в ответ с использованием экземпляра Stream

Эти описания взяты из MSDN и, за исключением FileStreamResult, первые три звука идентичны. Так в чем же разница между ними?

2 ответа

Решение

FileResult является абстрактным базовым классом для всех остальных.

  • FileContentResult - вы используете его, когда у вас есть байтовый массив, который вы хотели бы вернуть в виде файла
  • FilePathResult - когда у вас есть файл на диске и вы хотите вернуть его содержимое (вы указываете путь)
  • FileStreamResult - у вас есть открытый поток, вы хотите вернуть его содержимое в виде файла

Тем не менее, вам редко придется использовать эти классы - вы можете просто использовать один из Controller.File перегрузки и позвольте asp.net mvc сделать магию для вас

Отличный вопрос... и заслуживает более подробной информации. Я попал сюда в результате интересной ситуации. Мы доставляли некоторые вложения в формате PDF через среду MVC3/C#. Наш код был выпущен, и мы начали получать ответы от наших клиентов о том, что загрузка происходила странно, когда они использовали Chrome, и тип файла преобразовывался в "pdf-, attachment.pdf-, attachment". Да... ты понял... все это. Таким образом, можно переписать его так, чтобы он был просто "pdf", и файл все равно сохранялся бы неповрежденным, но что за беспорядок!

Итак, чтобы описать исходную ситуацию, мы устанавливали заголовок "Content-Disposition", а затем возвращали FileContentResult...

var cd = new System.Net.Mime.ContentDisposition
            {
                FileName = result.Attachment.FileName,
                Inline = false
            };
            Response.AppendHeader("Content-Disposition", cd.ToString());

return File(result.Attachment.Data, MimeExtensionHelper.GetMimeType(result.Attachment.FileName), result.Attachment.FileName);

Казалось, хорошо. Работал нормально в IE. Поэтому я провел небольшое исследование и попытался реализовать FileStreamResult (оставив установщик Content-Disposition):

MemoryStream dataStream = new MemoryStream();
dataStream.Write(result.Attachment.Data, 0, result.Attachment.Data.Length);
dataStream.Position = 0;
return new FileStreamResult(dataStream, MimeExtensionHelper.GetMimeType(result.Attachment.FileName));

Это исправило проблему в Chrome! Хммм... но почему, черт возьми, я должен взять мой совершенно хороший байтовый массив и передать его в поток, а затем вернуть его через него, чтобы заставить имя файла работать правильно?

Затем появился скрипач.

С FileContentResult я получил 2 Content-Dispositions в заголовке. С FileStreamResult я получил 1.

FileContentResult добавляет заголовок Content-Disposition при предоставлении имени файла, а Chrome рассматривает кратные значения этого заголовка как ошибку.

Странная реакция... но определенно это хорошо знать.

Другие вопросы по тегам