65

I need to return an image with a Web API Get method. The code below seems to work fine except that I get this message in the Fiddler's ImageView window, "This response is encoded, but does not claim to be an image."

public HttpResponseMessage Get()
{
    using (FileStream fs = new FileStream(filePath, FileMode.Open))
    {
        HttpResponseMessage response = new HttpResponseMessage(); 
        response.Content = new StreamContent(fs);
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
        return response;
    }
} 

I see the same result in the Fiddler with this code also:

public HttpResponseMessage Get()
{
    HttpResponseMessage response = new HttpResponseMessage();
    Byte[] b = (GetImageByteArray());
    response.Content = new ByteArrayContent(b);
    response.Content.LoadIntoBufferAsync(b.Length).Wait();
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
    return response;
}

I get the same result if I use .png format.

Appreciate your help,

LatentDenis
  • 2,839
  • 12
  • 48
  • 99
J.D.
  • 651
  • 1
  • 5
  • 5
  • Can you please provide detail about GetImageByteArray() method ? Also are you sure that image that you are reading is jpeg / jpg image and not other format image ? – dotnetstep Aug 27 '16 at 05:02

4 Answers4

84

If I understand correctly then you are asking specific to asp.net core. In ASP.net core HttpResponseMessage is not a way to return result the way we used to do in ASP.net web api 2.

In asp.net core ( WEB API ) simply look like this.

[HttpGet]
public IActionResult Get()
{            
    Byte[] b = System.IO.File.ReadAllBytes(@"E:\\Test.jpg");   // You can use your own method over here.         
    return File(b, "image/jpeg");
}

Note: As you mention that in Fiddler Imageview you see message like this "his response is encoded, but does not claim to be an image." because ASP.net core consider HttpResponseMessage as simple class and convert into json or xml.

LatentDenis
  • 2,839
  • 12
  • 48
  • 99
dotnetstep
  • 17,065
  • 5
  • 54
  • 72
  • Well, what counts is the final result. Your code does it very nicely. The heck with the HttpResponseMessage. :-) I am going to mark it as a correct answer. Thanks much, – J.D. Aug 27 '16 at 06:35
  • 15
    It's better to use the `File` method overload which accepts a stream, this way you don't to load the picture into the servers memory before sending it. `FileStream stream = File.Open(@"E:\\Test.jpg"); return File(stream, "image/jpeg");` or even easier: `return PhysicalFile("@E:\\Test.jpg", "image/jpg");` https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.Core/ControllerBase.cs#L711 – Tseng Aug 27 '16 at 09:53
  • This works better `return PhysicalFile(@"E:\Test.jpg", "image/jpg");` – Jussi Palo Apr 01 '19 at 18:49
  • See https://stackoverflow.com/a/35880687/8546258 to handle the content type programmatically (if so desired). – Yehuda Makarov Aug 18 '21 at 23:34
11

This is the way I get image from API in my project. I share for whom concern.

Image content save to Images folder in server and image name saved to Database.

[Route("api/dashboard/GetImage")]
public byte[] GetImage(int componentId)
{
            using (var dashboardService = new DashboardService())
            {
                var component = dashboardService.GetImage(componentId);
                var context = HttpContext.Current;
                string filePath = context.Server.MapPath("~/Images/" + component.ImageName);
                context.Response.ContentType = "image/jpeg";
                using (FileStream fileStream = new FileStream(filePath, FileMode.Open))
                {
                    using (var memoryStream = new MemoryStream())
                    {
                        fileStream.CopyTo(memoryStream);
                        Bitmap image = new Bitmap(1, 1);
                        image.Save(memoryStream, ImageFormat.Jpeg);

                        byte[] byteImage = memoryStream.ToArray();
                        return byteImage;
                    }
                }
            }
}

Get image content in Angular

this.dashboardService.getImage(this.componentId)
    .subscribe((blob: any) => {
      let objectURL = 'data:image/jpeg;base64,' + blob;
      this.imageUrl = this.sanitizer.bypassSecurityTrustUrl(objectURL);;
});
Hien Nguyen
  • 24,551
  • 7
  • 52
  • 62
10

Adding this answer because those comments are easy to miss (like I nearly did).

Suggested by Jussi Palo (using a PhysicalFileResult):

[HttpGet]
public IActionResult Get()
{        
    return PhysicalFile(@"E:\\Test.jpg", "image/jpeg");
}
  • A nice single liner that handles things like 206 partial.

Suggested by Tseng (using an overload of the FileContentResult constructor that accepts a stream):

[HttpGet]
public IActionResult Get()
{        
    FileStream stream = File.Open(@"E:\\Test.jpg");
    return File(stream, "image/jpeg");
}
  • Useful if your stream is coming from somewhere else (like an embedded resource).

For RL remember to check the file/resource exists, and return 404 if not.

Mark
  • 551
  • 6
  • 13
  • I am using the second approach, but I just cannot find a way to show image on my frontend. Using vue, and :src binding is just not working properly – Kadaj Mar 23 '23 at 14:56
-3

In addition to previous answers, use this to get image based on hosting environment within System.Web.Hosting namespace.

var imageUrl = HostingEnvironment.MapPath("~/images/photo.png");

and use imageUrl it to find byte[] of the image, and process with proper content-type like image/jpeg

byte[] binaryImage = File.ReadAllBytes(imageUrl);   
return File(binaryImage , "image/jpeg");

Make sure you have referenced System.IO namespace for File static method.

Bhuwan Maharjan
  • 515
  • 4
  • 7