2012-09-04 7 views
14

私は、ファイルIDのリストを渡してそれらのファイルのサムネイル画像を返す、ASP.NET MVC 4 Web Apiコントローラメソッドを持っています。1つのWebApiメソッドから複数のバイナリファイルを提供する最良の方法は何ですか?

ので、クライアントは、数値ID(例えば、10、303、29)のリストを渡すかもしれない、との方法は、サムネイル画像が少しこのようになります一覧を返します。その

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

理由を発信者はIDのリストを渡すのではなく、アイテムごとに1回の呼び出しで分かりやすくする必要があります。ダウンロードするアイテムは数十または数百になる可能性があります。個別にダウンロードするために必要なすべてのHTTPトラフィックを回避しようとしています。

現在、私はRestSharpとJSON.NETを使用していますので、ThumbnailImageオブジェクトがJSONとして渡されています。コーディングのシンプルさという点では問題ありませんが、JSONはバイナリデータを効率的に表現する方法ではありません。

私は、生のバイトをオクテットストリームとして返すべきだと考えています...しかし、私はそれを簡単に行うことができますが、私はそれを行う最良の方法は不明です複数の画像の場合、特に、IDやその他の情報を各ファイルに返す必要がある場合には、 (結果は必ずしも指定された順序で返されるわけではなく、いくつかのファイルが欠落している可能性があるため、IDは必須です。

Iは、単に項目ごとに、私は、画像データ自体に続く画像データの長続いID(適当に符号化された)、、、およびを書き込むように続いて、応答ストリームに断片的にすべてを書くことができます次の項目についても同じことによって、など

それはエンコーディングに関する仮定作り、排出されるまで、発信者は、単にストリームから読み続けるだろう(と長さを!)IDの、など

私はそれがうまくいくと思いますが、それはちょっとしたようです - 良い方法がありますか?

+0

如何でしょうかクライアントが画像を使用する、画像をWebページに表示する、アーカイブとしてダウンロードするなど何か他のもの – EBarr

+0

レスポンスをMultipartContentとして送信できるかどうかを知りたい場合は、内部コンテンツをStreamContentにして、 。 –

+0

@EBarr:クライアントアプリケーションも作成していますので、閉じた環境です。WinFormsアプリケーション内で画像を表示します(検索結果のサムネイルとして) –

答えて

10

OK、ここでは、KiranChallaが言及したMultipartContentを使用して動作するように見えるコードスニペットです。(これは、この場合には、整数のIDのリストだけ)であるJSONでエンコードされた「オブジェクト」(と一緒に、種類の異なる2つのファイルを戻す方法を示し単なるダミーサンプルです。

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

それは私のために働いていない。これは、有効な形式ではないファイルを1つだけ返します。私を助けてください。私はこれにこだわった –

0

すべてのサムネイルの中から圧縮ファイル(例:ZIPファイル)を作成して送信することができます。

その後、発信者はそのファイルを解凍するだけで済みます。複数のファイルを含む1つのファイルを送信することは、1つのストリームで複数のファイルを送信する方がはるかに受け入れられるようになります。

キャッシングを利用する可能性は低いです(使用パターンはもちろん)。

+0

しかし、私はまだ関連するすべての情報(例えばID)を渡すのと同じ問題(別の場所でも同じ問題を抱えている)を持っています...また、ZIPを解凍するのがなぜ簡単でないのか分かりませんファイルの連結ストリームを解凍しますか? –

+1

@GaryMcGill 'ZIP'は広く実装されています。単に圧縮するだけでなく、複数のファイルに対してストリーミング可能なコンテナ形式としても機能します。最初のファイルとして関連情報を持つ「ファイル」を作成し、実際のファイルのIDをファイル名として使用することができます。 ZIPの 'Store'圧縮モードを使用すると、質問で説明した' name、length、bytes'スキームになります。 –

1

私が見ている1つの課題は、返される画像の数に基づいて、発信者はタイムアウト値を調整する必要があることです。これが本屋の場合は、戻ってきたイメージがたくさんある可能性があります。

各画像のURLを送り返して、実際の画像を取得するために発信者に任せたらどうでしょうか?これは、複数の通話でトラフィックが少し増えることを意味しますが、発信者は後で情報をすぐに取り戻し、発信者の要件に基づいて画像を取得します。

私は間違っているかもしれませんが、残りのアイデアは、各リソースを特定し、多数のイメージをバンドルし、そのリソースを呼び出すことだと思いました。ちょっと考えました...

+0

私はこれに同意します。おそらくこのようなものをバンドルするのは非常にRESTfulではありませんが、実際にはこのWebサービスを使用する(唯一の)アプリケーションも書いているので、それは問題ないと思います。 –

+1

タイムアウト値については良い点がありますが、私もクライアントを書いているので、それにも対処できます。 (私はたぶん一度にダース程度しか要求しないでしょう)。 100枚の画像を送信するために必要な余分なトラフィックが多すぎると思うので、それらを個別に取得することは私には当てはまらない。 –