Я работаю над веб-сервисом, использующим новый WebAPI ASP.NET MVC, который будет обслуживать двоичные файлы, в основном .cab
и .exe
файлы.
Следующий метод контроллера, кажется, работает, это означает, что он возвращает файл, но он устанавливает тип содержимого application/json
:
public HttpResponseMessage<Stream> Post(string version, string environment, string filetype)
{
var path = @"C:\Temp\test.exe";
var stream = new FileStream(path, FileMode.Open);
return new HttpResponseMessage<Stream>(stream, new MediaTypeHeaderValue("application/octet-stream"));
}
Есть лучший способ сделать это?
asp.net
asp.net-mvc
asp.net-web-api
Джош Эрл
источник
источник
Ответы:
Попробуйте использовать простой
HttpResponseMessage
с егоContent
свойством, установленным вStreamContent
:Несколько замечаний по поводу
stream
использованного:Вы не должны вызывать
stream.Dispose()
, так как веб-API все еще должен иметь возможность доступа к нему, когда он обрабатывает методы контроллераresult
для отправки данных обратно клиенту. Поэтому не используйтеusing (var stream = …)
блок. Веб-API будет распоряжаться потоком для вас.Убедитесь, что текущая позиция потока установлена на 0 (то есть начало данных потока). В приведенном выше примере это дано, поскольку вы только что открыли файл. Однако в других случаях (например, когда вы первый написать несколько двоичных данных в
MemoryStream
), убедитесь ,stream.Seek(0, SeekOrigin.Begin);
или наборstream.Position = 0;
В случае файловых потоков явное указание
FileAccess.Read
разрешения может помочь предотвратить проблемы с правами доступа на веб-серверах; Учетным записям пула приложений IIS часто предоставляются только права на чтение / просмотр / выполнение доступа к wwwroot.источник
using
ни к result (HttpResponseMessage
), ни к самому потоку, так как они все равно будут использоваться вне метода. Как упоминалось @Dan, они удаляются платформой после того, как она отправит ответ клиенту.Для Web API 2 вы можете реализовать
IHttpActionResult
. Вот мой:Тогда как-то так в вашем контроллере:
И вот один из способов, которым вы можете указать IIS игнорировать запросы с расширением, чтобы запрос направлялся в контроллер:
источник
async
модификатор в сигнатуру метода и полностью удалить создание задачи: gist.github.com/ronnieoverby/ae0982c7832c531a9022Для тех, кто использует .NET Core:
Вы можете использовать интерфейс IActionResult в методе контроллера API, например так ...
Этот пример упрощен, но должен понять суть. В .NET Ядра этот процесс так намного проще , чем в предыдущих версиях .NET - т.е. нет тип ответа установка, содержание, заголовки и т.д.
Также, конечно, тип MIME для файла и расширение будут зависеть от индивидуальных потребностей.
Ссылка: ТАК Сообщение от @NKosi
источник
Хотя предлагаемое решение работает нормально, есть другой способ вернуть байтовый массив из контроллера с правильно отформатированным потоком ответов:
К сожалению, WebApi не содержит никакого средства форматирования для «application / octet-stream». Здесь на GitHub есть реализация: BinaryMediaTypeFormatter (есть небольшие изменения, чтобы заставить его работать для webapi 2, сигнатуры методов изменены).
Вы можете добавить этот форматер в вашу глобальную конфигурацию:
Теперь WebApi следует использовать,
BinaryMediaTypeFormatter
если в запросе указан правильный заголовок Accept.Я предпочитаю это решение, потому что контроллер действия, возвращающий byte [], более удобен для тестирования. Тем не менее, другое решение позволяет вам лучше контролировать, если вы хотите вернуть другой тип контента, чем «application / octet-stream» (например, «image / gif»).
источник
Если у вас есть проблема с вызовом API более одного раза при загрузке довольно большого файла с использованием метода в принятом ответе, установите для буферизации ответа значение true System.Web.HttpContext.Current.Response.Buffer = true;
Это гарантирует, что весь двоичный контент буферизируется на стороне сервера перед его отправкой клиенту. В противном случае вы увидите многократный запрос на контроллер, и если вы не обработаете его должным образом, файл будет поврежден.
источник
Buffer
Имущество является устаревшим в пользуBufferOutput
. По умолчанию оноtrue
.Используемая вами перегрузка устанавливает перечисление форматировщиков сериализации. Вы должны указать тип содержимого явно как:
источник
Content Type: application/json
в Fiddler.Content Type
, Как представляется, установлен правильно , если я нарушу до возвращенияhttpResponseMessage
ответа. Есть еще идеи?Вы могли бы попробовать
источник