16

我有一个 ASP.NET MVC 4 Web Api 控制器方法,它传递文件 ID 列表并返回这些文件的缩略图。

因此,客户端可能会传入一个数字 ID 列表(例如 10、303、29),并且该方法返回一个 List,其中 ThumbnailImage 看起来有点像这样:

class ThumbnailImage
{
    public int Id { get; set; }
    // Some other stuff
    public byte[] RawData { get; set; }
}

调用者传入一个 ID 列表而不是对每个项目进行一次调用的原因应该是显而易见的 - 可能有几十个或数百个项目要下载,我试图避免所有需要的 HTTP 流量单独下载它们。

目前,我正在使用 RestSharp 和 JSON.NET,因此我的 ThumbnailImage 对象作为 JSON 通过网络传递。从编码简单性的角度来看,这很好,但 JSON 不是表示二进制数据的有效方式。

所以,我认为我应该将原始字节作为八位字节流返回......但是,虽然我可以轻松地为单个图像执行此操作,但我不确定为多个图像执行此操作的最佳方法,特别是当我还需要返回每个文件的 ID 和其他信息时。(ID 是必需的,因为结果不一定会按给定顺序返回 - 并且某些文件可能会丢失)。

可以简单地将所有内容零碎地写入响应流,以便为每个项目写入 ID(适当编码),然后是图像数据的长度,然后是图像数据本身,然后是相同的内容下一项,等等。

然后,调用者将简单地继续从流中读取,直到用尽,对 ID 的编码(和长度!)等做出假设。

我认为这会奏效,但它似乎很笨拙 - 有没有更好的方法?

4

3 回答 3

16

好的,这是一段似乎可以工作的代码片段,它使用了 KiranChalla 提到的 MultipartContent。(这只是一个虚拟示例,它展示了如何返回两个不同类型的文件,以及一个 JSON 编码的“对象”(在这种情况下,它只是一个整数 ID 列表)。

public HttpResponseMessage Get()
{
    var content = new MultipartContent();
    var ids = new List<int>() { 1, 2 };

    var objectContent = new ObjectContent<List<int>>(ids, new System.Net.Http.Formatting.JsonMediaTypeFormatter());
    content.Add(objectContent);

    var file1Content = new StreamContent(new FileStream(@"c:\temp\desert.jpg", FileMode.Open));
    file1Content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("image/jpeg");
    content.Add(file1Content);

    var file2Content = new StreamContent(new FileStream(@"c:\temp\test.txt", FileMode.Open));
    file2Content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("text/plain");
    content.Add(file2Content);

    var response = new HttpResponseMessage();
    response.Content = content;
    return response;
}
于 2012-09-08T21:14:38.017 回答
1

您可以从所有缩略图中创建一个压缩文件(例如 ZIP 文件)并将其发回。

然后调用者只需将其解压缩 - 发送包含多个文件的单个文件将比在单个流中发送多个文件更容易接受。

缺点是您不太可能利用缓存(当然取决于您的使用模式)。

于 2012-09-04T15:14:33.837 回答
1

我看到的一个挑战是,根据发回的图像数量,调用者必须调整它们的超时值。如果这是书店,可能会发回很多图像。

如果您只发回每张图片的 url 并将其留给调用者获取实际图片怎么办?这意味着多次调用会增加一点流量,但调用者会迟早得到信息,然后根据调用者的要求获取图像。

我可能是错的,但我认为 rest 背后的想法是识别每个资源,而不是捆绑一堆图像并将其称为资源。只是一个想法...

于 2012-09-04T16:48:09.620 回答