【问题标题】:ASP .Net Web API downloading images as binaryASP .Net Web API 将图像下载为二进制
【发布时间】:2015-07-02 23:46:01
【问题描述】:

我想尝试使用 Web API 进行休息调用,但我希望响应是存储在数据库中的实际二进制图像,而不是 JSON base64 编码字符串。有人对此有所指点吗?

更新- 这就是我最终实现的:

 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;

【问题讨论】:

标签: asp.net rest asp.net-web-api


【解决方案1】:

您可以将响应内容设置为 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);

【讨论】:

  • 将您的答案标记为答案,因为它是对问题的直接回应,并且最接近我的需要。感谢您花时间回答!
  • 有关如何从 Web API 返回文件的解决方案,请查看他在stackoverflow.com/a/14819168/179138 的答案的最后部分
【解决方案2】:

虽然这已被标记为已回答,但这并不是我想要的,所以我一直在寻找。现在我已经弄清楚了,这就是我所拥有的:

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))

编辑:没关系,这是针对常规 MVC 的。对于 Web 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 非常相似。

【讨论】:

  • 就我而言,我需要 Web API 版本。
  • FileStream 对象怎么样...有谁知道 httpResponseMessage 上的 Dispose() 默认方法是否会正确销毁 Stream?我们的安全扫描将此突出显示为未解决的潜在资源泄漏。
【解决方案3】:

我确实做了这件事。这是我的代码:

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

【讨论】:

    【解决方案4】:

    这项任务很容易使用 WebAPI 的情况下完成。我会为一个独特的扩展实现一个自定义的HTTP handler,并在那里返回二进制响应。优点是您还可以修改 HTTP 响应标头和内容类型,因此您可以完全控制返回的内容。

    您可以设计一个 URL 模式(定义您如何知道根据其 URL 返回的图像),并将这些 URL 保留在您的 API 资源中。一旦在 API 响应中返回 URL,浏览器就可以直接请求它,并到达您的 HTTP 处理程序,返回正确的图像。

    图像是静态内容,在 HTTP 和 HTML 中具有自己的作用 - 无需将它们与使用 API 时使用的 JSON 混合。

    【讨论】:

    • 我认为 OP 想知道如何使用 webapi 而不是如何避免使用 webapi。
    • 正确,我知道 HTTP 处理程序路由并考虑了它,但不希望我的代码像那样拆分。感谢您抽出时间回复。
    • 好吧,就我的两分钱。我一直发现使用 HTTP 处理程序更容易。
    • 性能也是一个因素。不确定处理程序与 Web API,但如果您使用 Http Module 对 IIS 中的静态文件执行 URL 重写,您将获得 IIS 静态文件处理程序的性能优势。
    猜你喜欢
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多