2016-05-04 2 views
12

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

Внутри моей 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 я получаю:

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

(при прохождении через FileStream Скрипач показывает мне изображение.)

+0

Вы пробовали сбросить 'memoryStream.Position' до 0, как вы это делали в прокомментированном коде? – itsme86

+0

это одна из многих вещей, которые я пробовал ... нет радости, спасибо, хотя –

ответ

16

В коде поток памяти расположены, прежде чем он может передать его содержание в ответ. Возвращенный ответ будет использовать выделенный поток памяти, чтобы не было возврата, следовательно, 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; 
+0

Идеальный улов, спасибо! –

+0

Рад помочь. Я ударил головой об этой проблеме слишком много раз в прошлом, когда пытался генерировать PDF-файлы, и один и тот же образ проходил через ситуации. Живи и учись. :) – Nkosi