В чем разница между четырьмя результатами файлов в 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 рассматривает кратные значения этого заголовка как ошибку.
Странная реакция... но определенно это хорошо знать.