Web API Controller преобразует MemoryStream в StreamContent - программирование
Подтвердить что ты не робот

Web API Controller преобразует MemoryStream в StreamContent

У меня есть большая коллекция изображений, хранящихся на защищенном сервере, некоторые из которых должны отображаться на портале, обращенном к миру. Сервер портала находится в DMZ, который разрешает запросы, но не позволяет прямым запросам переходить в защищенный домен. Изображения каталогизируются с помощью SOLR и могут быть загружены через внутренний (apache?) Сервер из http://intenalname/folderA/folderAB/file.jpg

Внутри моего PhotoController я могу создать экземпляр WebClient, указать ему url и получить MemoryStream. Если я попытаюсь использовать этот поток памяти для заполнения response.content, я получаю пустой ответ (для каждого скрипача). Если я использую поток памяти для записи в локальный файл, тогда прочитайте файл (используя FileStream и FileInfo), он работает "как ожидалось".

Я мог бы получить от MemoryStream до StreamContent без прохождения файловой системы (не должен я)?? но как? Конструктор по умолчанию для StreamContent(stream) принимает экземпляр потока памяти без ошибки компилятора... но он просто "не работает".

HttpResponseMessage response = Request.CreateResponse();

using (WebClient webClient = new WebClient())
{
    string url = string.Format(PHOTO_GET, filePath);
    using (MemoryStream memoryStream = new MemoryStream(webClient.DownloadData(url)))
    {
        // If these lines are unremarked the stream moves 'through' the file system and works (?!)
        //memoryStream.Position = 0;
        //string tempName = @"c:\test\" + Guid.NewGuid().ToString() + ".jpg";
        //var fs = new FileStream(tempName, FileMode.OpenOrCreate);
        //stream.CopyTo(fs);
        //fs.Close();
        //FileInfo fi = new FileInfo(tempName);

        response.Headers.AcceptRanges.Add("bytes");
        response.StatusCode = HttpStatusCode.OK;
        //response.Content =  new StreamContent(fi.ReadStream());
        response.Content = new StreamContent(memoryStream);
        response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("render");
        response.Content.Headers.ContentDisposition.FileName = fileName;
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpg");//("application/octet-stream");
        response.Content.Headers.ContentLength = memoryStream.Length;

    }

}
return response;

При тестировании через Fiddler я получаю:

[Fiddler] ReadResponse() не удалось: сервер не вернул полный ответ на этот запрос. Сервер вернул 0 байт.

(при просмотре FileStream Fiddler показывает мне изображение.)

4b9b3361

Ответ 1

В вашем коде поток памяти удаляется, прежде чем он сможет передать его содержимое в ответ. Возвращенный ответ будет использовать выделенный поток памяти, чтобы не было возврата, следовательно, 0 байтов в скрипаче.

HttpResponseMessage response = Request.CreateResponse();

using (WebClient webClient = new WebClient())
{
    string url = string.Format(PHOTO_GET, filePath);
    var memoryStream = new MemoryStream(webClient.DownloadData(url));

    response.Headers.AcceptRanges.Add("bytes");
    response.StatusCode = HttpStatusCode.OK;
    response.Content = new StreamContent(memoryStream);
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("render");
    response.Content.Headers.ContentDisposition.FileName = fileName;
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpg");
    response.Content.Headers.ContentLength = memoryStream.Length;            
}
return response;