【问题标题】:Returning Images from WebApi从 WebApi 返回图像
【发布时间】:2017-09-14 22:59:43
【问题描述】:

我正在制作一个 Web Api,我需要向客户端返回多个图像。我目前为每个图像使用 Base64 字符串,但这会导致每个请求花费的时间太长。有没有更好、更高效的图片返回方式?

这是我正在使用的代码:

控制器:

    public LearningUnits GetLearningUnits([FromODataUri]Guid key)
    {
        var record = db.LearningUnits.SingleOrDefault(inst => inst.LearningUnitId == key);

        record.ImageURLPath = ImageHandler.ImageToByteArrayFromFilePath(record.ImageURLPath);

        return record;
    }

ImageToByteArray 方法:

    public static string ImageToByteArrayFromFilePath(string imagefilePath)
    {
        byte[] imageArray = File.ReadAllBytes(imagefilePath);

        string baseImage = Convert.ToBase64String(imageArray);

        return baseImage;
    }

【问题讨论】:

  • 这样的图片一共有多少张?
  • 为什么不能在模型中返回url,然后客户端会进一步请求获取图像二进制文件?
  • 取决于数据库中的记录数量。每条记录都有一个图像。所以它可能是 1 到 1000。
  • @WadeFerreira:返回“1000 张图像”肯定会解释为什么请求需要很长时间。 通常 API 会返回引用其他资源(例如图像)的数据,方法是提供这些资源的 URL,并且数据的消费者会根据需要对这些其他资源发出单独的请求。当客户请求 1000 条记录时,他们真的会在同一个请求中也想要所有这些图像吗?这些数据的用例是什么?
  • @Mufaka - 你说得对,我错过了,现在在 OPs 代码中看到了。

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


【解决方案1】:

如果端点返回 json,那么除了base64,没有其他方法可以在响应中嵌入二进制文件。但由于性能问题,这绝对是一个坏主意。可能对于某些图标来说还可以,但对于较大的图像则不合适。

因此,这里最好的解决方案是将 url 返回到图像。客户端将进一步请求获取图像的原始字节。

另外值得一提的是,图像 url 不仅可以是静态文件的路径,还可以是某个 webapi 端点的路径,例如,通过资源 id 获取图像字节并发送客户端原始二进制文件返回,而不是 json 字符串。

【讨论】:

  • 我决定走这条路。我还没有找到更好的选择,这将是最有效的
【解决方案2】:

解决方案是使用媒体格式化程序,这样当使用特定类型查询 Web API 时,您将收到特定类型的实际二进制流。

http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters

这是标准的 RESTful 模式;您有相同的 URL,但是当您想要数据的 JSON 记录时,您接受类型:应用程序/json,但是当您想要该媒体类型时,您将 MIME 请求类型更改为 image/png 或类似的东西。

更多信息可以在这里找到: How to provide custom mediatype formats for OData Api

Odata 也在这里隐式支持它:https://msdn.microsoft.com/en-us/library/system.web.http.odata.formatter.odatamediatypeformatter(v=vs.118).aspx

【讨论】:

  • 为单个端点返回不同的数据不是一个好主意。 MediaFormatters 仅适用于 same 数据的不同格式。否则,它会破坏单一职责原则,并且不是常见的 RESTful 模式。当然,您可以返回图像而不是 json,但前提是图像完全代表数据。
  • 我不同意;如果图像代表相关实体,那么您可以争辩说它是该特定实体的内容类型。如果数据实体只有一个图像可视化,那么即使图像不是整个实体的完整表示(无论如何可能包括来自 OData 之类的遥测等),该图像可视化也是合适的。如果我们将您的逻辑得出完整结论,那么我们甚至不应该将对象表示为 application/json 或 application/xml,因为它与数据的本机形式根本不同。
  • 命名MediaType**Formatter** 表示,只有实体的格式化程序不同。当然,通过将数据序列化为特定类型,可能会出现更多或更少的信息。考虑端点[get]/api/v1/blog/123,当使用accept:image/png 请求它时,仅返回博客文章的主图像是不够的,但如果您生成带有标题的图像就可以了。如果有人只想返回像ImageURLPath 这样的属性值,则应定义显式端点:[get]/api/v1/blog/123/image
猜你喜欢
  • 2017-04-09
  • 1970-01-01
  • 2018-12-17
  • 2019-01-10
  • 2017-06-04
  • 1970-01-01
  • 1970-01-01
  • 2011-05-27
  • 2016-05-20
相关资源
最近更新 更多