2012-05-08 2 views
29

Я хочу попытаться использовать веб-API, чтобы сделать вызов для отдыха, но я хочу, чтобы ответ был фактическим двоичным изображением, хранящимся в базе данных, а не кодировкой JSON base64. У кого-то есть некоторые указатели на это?ASP. Net Web API загружает изображения как двоичные

Обновление- Это то, что я в конечном итоге реализации:

HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); 
result.Content = new StreamContent(new MemoryStream(profile.Avatar)); 
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); 
result.Content.Headers.ContentDisposition.FileName = "avatar.png"; 
return result; 
+0

Я думаю, что эта статья задает подобный вопрос http://stackoverflow.com/questions/8340247/returning- a-image-from-a-restful-wcf-service –

ответ

28

Вы можете установить содержимое ответа на объект StreamContent:

 var fileStream = new FileStream(path, FileMode.Open); 

     var resp = new HttpResponseMessage() 
     { 
      Content = new StreamContent(fileStream) 
     }; 

     // Find the MIME type 
     string mimeType = _extensions[Path.GetExtension(path)]; 
     resp.Content.Headers.ContentType = new MediaTypeHeaderValue(mimeType); 
+2

Отмечено как ответ, потому что это был прямой ответ на вопрос и был ближе всего к тому, что мне нужно. Спасибо, что нашли время ответить! – spaceagestereo

+0

Для решения вопроса о том, как вернуть файл из веб-API, взгляните на самый конец своего собственного ответа по адресу http://stackoverflow.com/a/14819168/179138 –

0

Эта задача очень легко реализовать без использования WebAPI. Я бы выполнил заказ HTTP handler для уникального расширения и вернул туда двоичный ответ. Плюс заключается в том, что вы также можете изменять заголовки и тип содержимого HTTP-ответа, поэтому у вас есть абсолютный контроль над возвращаемым.

Вы можете разработать шаблон URL (определяющий, как вы знаете, какое изображение будет возвращаться на основе его URL-адреса) и сохранить эти URL-адреса в своих ресурсах API. Как только URL-адрес возвращается в ответ API, он может быть запрошен непосредственно браузером и достигнет вашего обработчика HTTP, вернув правильное изображение.

Изображения представляют собой статический контент и имеют свою собственную роль в HTTP и HTML - не нужно смешивать их с JSON, который используется при работе с API.

+10

Я думаю, что OP хочет знать, как это сделать ** с webapi ** вместо того, чтобы избежать webapi. – EBarr

+0

Правильно, я знаю маршрут HTTP-обработчика и считал его, но не хотел, чтобы мой код так разбился. Спасибо, что нашли время ответить. – spaceagestereo

+0

Ну, только мои два цента.Мне всегда было легче с обработчиками HTTP. – Slavo

16

Хотя это было отмечено как ответ, это было не совсем то, что я хотел, поэтому я продолжал смотреть. Теперь, когда я понял это, вот что я получил:

public FileContentResult GetFile(string id) 
{ 
    byte[] fileContents; 
    using (MemoryStream memoryStream = new MemoryStream()) 
    { 
     using (Bitmap image = new Bitmap(WebRequest.Create(myURL).GetResponse().GetResponseStream())) 
      image.Save(memoryStream, ImageFormat.Jpeg); 
     fileContents = memoryStream.ToArray(); 
    } 
    return new FileContentResult(fileContents, "image/jpg"); 
} 

Конечно, это получение изображения через URL. Если вы просто хотите, чтобы захватить изображение с файлом на сервере, я полагаю, вы замените эту строку:

using (Bitmap image = new Bitmap(WebRequest.Create(myURL).GetResponse().GetResponseStream())) 

с этим:

using (Bitmap image = new Bitmap(myFilePath)) 

EDIT: Никогда не возражаете, это для регулярного MVC. для веб-API, у меня есть следующее:

public HttpResponseMessage Get(string id) 
{ 
    string fileName = string.Format("{0}.jpg", id); 
    if (!FileProvider.Exists(fileName)) 
     throw new HttpResponseException(HttpStatusCode.NotFound); 

    FileStream fileStream = FileProvider.Open(fileName); 
    HttpResponseMessage response = new HttpResponseMessage { Content = new StreamContent(fileStream) }; 
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpg"); 
    response.Content.Headers.ContentLength = FileProvider.GetLength(fileName); 
    return response; 
} 

Это очень похоже на то, что имеет OP.

+0

В моем случае мне нужна версия веб-API. –

+0

Что касается объекта FileStream ... кто-нибудь знает, будет ли метод Dispose() по умолчанию для httpResponseMessage правильно уничтожить Stream? Наше сканирование безопасности подчеркивает это как неразрешенную потенциальную утечку ресурсов. – jessewolfe

1

Я сделал это точно. Вот мой код:

if (!String.IsNullOrWhiteSpace(imageName)) 
       { 
        var savedFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Path.Combine(uploadPath, imageName)); 
        var image = System.Drawing.Image.FromFile(savedFileName); 

        if (ImageFormat.Jpeg.Equals(image.RawFormat)) 
        { 
         // JPEG 
         using(var memoryStream = new MemoryStream()) 
         { 
          image.Save(memoryStream, ImageFormat.Jpeg); 

          var result = new HttpResponseMessage(HttpStatusCode.OK) 
           { 
            Content = new ByteArrayContent(memoryStream.ToArray()) 
           }; 

          result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg"); 
          result.Content.Headers.ContentLength = memoryStream.Length; 

          return result; 
         } 
        } 
        else if (ImageFormat.Png.Equals(image.RawFormat)) 
        { 
         // PNG 
         using (var memoryStream = new MemoryStream()) 
         { 
          image.Save(memoryStream, ImageFormat.Png); 

          var result = new HttpResponseMessage(HttpStatusCode.OK) 
          { 
           Content = new ByteArrayContent(memoryStream.ToArray()) 
          }; 

          result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png"); 
          result.Content.Headers.ContentLength = memoryStream.Length; 

          return result; 
         } 
        } 
        else if (ImageFormat.Gif.Equals(image.RawFormat)) 
        { 
         // GIF 
         using (var memoryStream = new MemoryStream()) 
         { 
          image.Save(memoryStream, ImageFormat.Gif); 

          var result = new HttpResponseMessage(HttpStatusCode.OK) 
          { 
           Content = new ByteArrayContent(memoryStream.ToArray()) 
          }; 

          result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/gif"); 
          result.Content.Headers.ContentLength = memoryStream.Length; 

          return result; 
         } 
        } 
       } 

А потом на клиенте:

    var client = new HttpClient(); 
        var imageName = product.ImageUrl.Replace("~/Uploads/", ""); 
       var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, 
             Properties.Settings.Default.DeviceMediaPath + "\\" + imageName); 

       var response = 
        client.GetAsync(apiUrl + "/Image?apiLoginId=" + apiLoginId + "&authorizationToken=" + authToken + 
            "&imageName=" + product.ImageUrl.Replace("~/Uploads/","")).Result; 

       if (response.IsSuccessStatusCode) 
       { 
        var data = response.Content.ReadAsByteArrayAsync().Result; 
        using (var ms = new MemoryStream(data)) 
        { 
         using (var fs = File.Create(path)) 
         { 
          ms.CopyTo(fs); 
         } 
        } 

        result = true; 
       } 
       else 
       { 
        result = false; 
        break; 
       } 
Смежные вопросы