2012-09-04 9 views
14

Tengo un método de controlador Web Api ASP.NET MVC 4 al que se le pasa una lista de ID de archivo y devuelve imágenes en miniatura para esos archivos.¿Cuál es la mejor manera de servir varios archivos binarios a partir de un único método WebApi?

Así, el cliente puede pasar en una lista de identificadores numéricos (por ejemplo, 10, 303, 29), y el método devuelve una lista donde un thumbnailImage se ve un poco como esto:

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

La razón por la que la persona que llama transfiere una lista de ID en lugar de hacer una llamada por elemento con la esperanza de ser obvio: puede haber docenas o cientos de elementos para descargar, y estoy tratando de evitar todo el tráfico HTTP que se requeriría para descargarlos individualmente .

Actualmente, estoy usando RestSharp y JSON.NET, por lo que mis objetos ThumbnailImage se pasan a través del cable como JSON. Está bien desde el punto de vista de la simplicidad de la codificación, pero JSON no es una forma eficiente de representar esos datos binarios.

Por lo tanto, estoy pensando que debería devolver los bytes sin formato como una secuencia de octetos ... sin embargo, aunque puedo hacerlo fácilmente para una sola imagen, no estoy seguro de la mejor manera de hacerlo para múltiples imágenes, especialmente cuando también necesito devolver la identificación y otra información diversa para cada archivo. (Se requiere la ID porque los resultados no se devolverán necesariamente en un orden determinado, y algunos archivos pueden faltar).

I podía simplemente escribir todo poco a poco en la corriente de respuesta, de modo que para cada elemento escribo el ID (adecuadamente codificada), seguido por la longitud de los datos de imagen, seguido de los propios datos de imagen, y luego seguido por lo mismo para el siguiente elemento, etc.

la persona que llama que luego simplemente seguir leyendo de la corriente hasta que se agotó, hacer suposiciones acerca de la codificación (y longitud!) de las identificaciones, etc.

Creo que funcionaría, pero parece torpe: ¿hay una mejor manera?

+0

¿Cómo se el cliente usa las imágenes, ¿las imágenes se muestran en una página web o para descargarlas como archivo? ¿Algo más? – EBarr

+0

¿Se pregunta si puede enviar la respuesta como un contenido multipartido donde los contenidos internos podrían ser StreamContent con el flujo de bytes sin formato? –

+0

@EBarr: también estoy escribiendo la aplicación cliente, por lo que es un entorno cerrado. Mostraré las imágenes en una aplicación WinForms (como miniaturas de resultados de búsqueda). –

Respuesta

10

OK, aquí hay un fragmento de código que parece funcionar, usando el contenido Multipart que se refiere KiranChalla.(Esto es sólo una muestra ficticia que muestra cómo devolver dos archivos de distintos tipos, junto con un "objeto" JSON-codificado (que en este caso es sólo una lista de número entero IDs).

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

no funciona para mí. Es solo un archivo que devuelve un formato no válido. por favor, ayúdame. Me quedé con esto –

0

Puede crear un archivo comprimido (por ejemplo, un archivo ZIP) de todas las miniaturas y enviarlo de vuelta.

Luego, la persona que llama solo tiene que descomprimirla en su extremo; enviar un solo archivo que contenga varios archivos será mucho más aceptable que enviar múltiples archivos en una sola transmisión.

La desventaja es que es menos probable que pueda aprovechar el almacenamiento en caché (según sus patrones de uso, por supuesto).

+0

Pero todavía tengo el mismo problema (aunque en otro lugar) de pasar toda la información relacionada (por ejemplo, el ID) ... Además, realmente no veo por qué es más fácil descomprimir un ZIP de lo que es descomprimir una secuencia concatenada de archivos? –

+1

@GaryMcGill 'ZIP' está ampliamente implementado. No solo comprime, sino que también actúa como un formato de contenedor transitable para múltiples archivos. Puede tener un "archivo" con información relacionada como su primer archivo y usar los ID de los archivos reales como nombres de archivo. Si usa el modo de compresión 'Store' de ZIP, será efectivamente el esquema' name, length, bytes' que describió en la pregunta. –

1

Uno de los desafíos que veo es que, según el número de imágenes que se envían, la persona que llama tiene que ajustar su valor de tiempo de espera. Si esto fuera por una librería, podrían enviarse muchas imágenes.

¿Qué sucede si solo devolviste las URL de cada imagen y deja que la persona que llama obtenga la imagen real? Significaría un poco más de tráfico con múltiples llamadas, pero la persona que llama recibiría información más temprano que tarde y luego obtendría las imágenes según los requisitos de la persona que llama.

Podría estar equivocado, pero pensé que la idea detrás del descanso era identificar cada recurso versus agrupar un montón de imágenes y llamar a eso un recurso. Solo un pensamiento ...

+0

Acepto, probablemente no sea muy RESTANTE agrupar las cosas de esta manera, pero en realidad también estoy escribiendo la (única) aplicación que usará este servicio web, así que creo que está bien. –

+1

Buen punto sobre el valor de tiempo de espera, aunque como también estoy escribiendo el cliente, también puedo lidiar con eso. (Probablemente solo solicite una docena más o menos a la vez). Creo que el tráfico adicional requerido para enviar 100 imágenes es demasiado difícil de soportar, por lo que buscarlas individualmente no me suena bien. –

Cuestiones relacionadas