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

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

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

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

Ответ 1

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

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

Однако вам редко придется использовать эти классы - вы можете просто использовать одну из перегрузок Controller.File и позволить ASP.NET MVC сделать магию за вас.

Ответ 2

Отличный вопрос... и заслуживает более подробной информации. Я оказался здесь в результате интересной ситуации. Мы поставляли некоторые вложения PDF через среду MVC3/С#. Наш код был выпущен, и мы начали получать ответы от наших клиентов о том, что загрузки ведут себя странно, когда они используют 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 вместо этого (поддерживая Set-Content Setter):

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! Hmmm... но почему в heck я должен взять свой превосходный массив байтов и передать его, а затем вернуть его через это, чтобы получить правильное имя файла?

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

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

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

Нечетная реакция... но определенно одна, что хорошо знать.