【问题标题】:How to to return an image with Web API Get method如何使用 Web API Get 方法返回图像
【发布时间】:2017-01-03 19:00:45
【问题描述】:

我需要使用 Web API Get 方法返回图像。下面的代码似乎工作正常,除了我在 Fiddler 的 ImageView 窗口中收到此消息,“此响应已编码,但不声称是图像。”

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

我在 Fiddler 中也看到了与此代码相同的结果:

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

如果我使用 .png 格式,我会得到相同的结果。

感谢您的帮助,

【问题讨论】:

  • 您能否提供有关 GetImageByteArray() 方法的详细信息?您还确定您正在阅读的图像是 jpeg / jpg 图像而不是其他格式的图像吗?

标签: c# asp.net-web-api asp.net-core


【解决方案1】:

如果我理解正确,那么您是在询问特定于 asp.net 核心的问题。在 ASP.net 核心中,HttpResponseMessage 不是我们过去在 ASP.net web api 2 中返回结果的方式。

在 asp.net core ( WEB API ) 中看起来像这样。

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

注意:正如您提到的,在 Fiddler Imageview 中,您会看到类似这样的消息“他的响应已编码,但不声称是图像。”因为 ASP.net 核心将 HttpResponseMessage 视为简单类并转换为 json 或 xml。

【讨论】:

  • 嗯,重要的是最终结果。你的代码做得很好。见鬼的 HttpResponseMessage。 :-) 我会将其标记为正确答案。非常感谢,
  • 最好使用接受流的File 方法重载,这样您就不会在发送之前将图片加载到服务器内存中。 FileStream stream = File.Open(@"E:\\Test.jpg"); return File(stream, "image/jpeg"); 甚至更简单:return PhysicalFile("@E:\\Test.jpg", "image/jpg"); github.com/aspnet/Mvc/blob/dev/src/…
  • 这个效果更好return PhysicalFile(@"E:\Test.jpg", "image/jpg");
  • 参见stackoverflow.com/a/35880687/8546258 以编程方式处理内容类型(如果需要)。
【解决方案2】:

这是我在项目中从 API 获取图像的方式。我为谁担心。

图像内容保存到服务器中的图像文件夹,图像名称保存到数据库。

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

在 Angular 中获取图片内容

this.dashboardService.getImage(this.componentId)
    .subscribe((blob: any) => {
      let objectURL = 'data:image/jpeg;base64,' + blob;
      this.imageUrl = this.sanitizer.bypassSecurityTrustUrl(objectURL);;
});

【讨论】:

    【解决方案3】:

    添加这个答案是因为这些 cmets 很容易错过(就像我几乎一样)。

    由 Jussi Palo 建议(使用 PhysicalFileResult):

    [HttpGet]
    public IActionResult Get()
    {        
        return PhysicalFile(@"E:\\Test.jpg", "image/jpeg");
    }
    
    • 一个很好的单班轮,可以处理像 206 partial 这样的事情。

    由 Tseng 建议(使用接受流的 FileContentResult 构造函数的重载):

    [HttpGet]
    public IActionResult Get()
    {        
        FileStream stream = File.Open(@"E:\\Test.jpg");
        return File(stream, "image/jpeg");
    }
    
    • 如果您的流来自其他地方(如嵌入式资源),则很有用。

    对于 RL,请记住检查文件/资源​​是否存在,如果不存在则返回 404。

    【讨论】:

      【解决方案4】:

      除了以前的答案,使用它来获取基于System.Web.Hosting命名空间内的托管环境的图像。

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

      并使用imageUrl查找图片的byte[],并使用image/jpeg等适当的内容类型进行处理

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

      确保您已为 File 静态方法引用 System.IO 命名空间。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-10
        • 2016-04-27
        相关资源
        最近更新 更多