2012-05-08 43 views
29

Tôi muốn thử sử dụng API Web thực hiện cuộc gọi còn lại nhưng tôi muốn phản hồi là hình ảnh nhị phân thực được lưu trữ trong cơ sở dữ liệu chứ không phải chuỗi mã hóa base64 JSON. Bất cứ ai có một số gợi ý về điều này?ASP .Net Web API tải xuống hình ảnh dưới dạng nhị phân

Update- Đây là những gì tôi đã kết thúc thực hiện:

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

Tôi nghĩ rằng bài viết này hỏi một câu hỏi tương tự http://stackoverflow.com/questions/8340247/returning- an-image-from-a-restful-wcf-service –

Trả lời

28

Bạn có thể thiết lập các nội dung đối phó với một đối tượng 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

Đánh dấu câu trả lời của bạn là câu trả lời vì đó là câu trả lời trực tiếp cho câu hỏi và gần nhất với những gì tôi cần. Cảm ơn đã dành thời gian trả lời! – spaceagestereo

+0

Để biết giải pháp về cách trả lại tệp từ API Web, hãy xem phần cuối câu trả lời của riêng mình tại http://stackoverflow.com/a/14819168/179138 –

0

Nhiệm vụ này được nhiều dễ dàng đạt được mà không cần sử dụng WebAPI. Tôi sẽ triển khai một tuỳ chỉnh HTTP handler cho một tiện ích mở rộng duy nhất và trả về phản hồi nhị phân tại đó. Điểm cộng là bạn cũng có thể sửa đổi các tiêu đề và kiểu nội dung phản hồi HTTP, vì vậy bạn có quyền kiểm soát tuyệt đối đối với những gì được trả về.

Bạn có thể tạo mẫu URL (xác định cách bạn biết hình ảnh nào cần trả lại dựa trên URL của nó) và giữ các URL đó trong tài nguyên API của bạn. Khi URL được trả về trong phản hồi API, nó có thể được trình duyệt yêu cầu trực tiếp và sẽ đến trình xử lý HTTP của bạn, trả về đúng hình ảnh.

Hình ảnh là nội dung tĩnh và có vai trò riêng trong HTTP và HTML - không cần trộn chúng với JSON được sử dụng khi làm việc với API.

+10

Tôi nghĩ rằng OP muốn biết cách thực hiện điều này ** với webapi ** thay vì cách tránh webapi. – EBarr

+0

Đúng, tôi biết về con đường xử lý HTTP và xem nó nhưng không muốn mã của tôi bị phân chia như thế. Cảm ơn bạn đã dành thời gian trả lời. – spaceagestereo

+0

Vâng, chỉ hai xu của tôi.Tôi luôn thấy dễ dàng hơn với trình xử lý HTTP. – Slavo

16

Trong khi điều này đã được đánh dấu là đã trả lời, nó không hoàn toàn là những gì tôi muốn, vì vậy tôi tiếp tục tìm kiếm. Bây giờ tôi đã tìm ra, đây là những gì tôi có:

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"); 
} 

Được cấp, đó là để nhận hình ảnh qua URL. Nếu bạn chỉ muốn lấy một hình ảnh ra khỏi máy chủ tập tin, tôi tưởng tượng bạn thay thế dòng này:

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

Với điều này:

using (Bitmap image = new Bitmap(myFilePath)) 

EDIT: Không sao, này là dành cho MVC thường xuyên. đối với API Web, tôi có điều này:

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; 
} 

Điều này khá giống với những gì OP có.

+0

Trong trường hợp của tôi, tôi cần phiên bản API Web. –

+0

Còn đối tượng FileStream thì có ai biết nếu phương thức mặc định Dispose() trên httpResponseMessage có phá hủy đúng Stream không? Quét bảo mật của chúng tôi đang làm nổi bật điều này như một sự rò rỉ tài nguyên tiềm năng chưa được giải quyết. – jessewolfe

1

Tôi đã làm điều này chính xác. Đây là mã của tôi:

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; 
         } 
        } 
       } 

Và sau đó trên máy khách:

    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; 
       } 
Các vấn đề liên quan