15

インメモリJPEGファイル(MemoryStreamオブジェクト)のコレクションからストリーミングされた圧縮zipファイルを生成して返すWebAPIコントローラーを作成するにはどうすればよいですか。DotNetZipライブラリを使用しようとしています。私はこの例を見つけました:http ://www.4guysfromrolla.com/articles/092910-1.aspx#postadlink 。ただし、Response.OutputStreamはWeb APIで使用できないため、この手法は完全には機能しません。そのため、zipファイルを新しいMemoryStreamに保存してみました。しかし、それは投げました。最後に、PushStreamContentを使用してみました。これが私のコードです:

    public HttpResponseMessage Get(string imageIDsList) {
        var imageIDs = imageIDsList.Split(',').Select(_ => int.Parse(_));
        var any = _dataContext.DeepZoomImages.Select(_ => _.ImageID).Where(_ => imageIDs.Contains(_)).Any();
        if (!any) {
            throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
        }
        var dzImages = _dataContext.DeepZoomImages.Where(_ => imageIDs.Contains(_.ImageID));
        using (var zipFile = new ZipFile()) {
            foreach (var dzImage in dzImages) {
                var bitmap = GetFullSizeBitmap(dzImage);
                var memoryStream = new MemoryStream();
                bitmap.Save(memoryStream, ImageFormat.Jpeg);
                var fileName = string.Format("{0}.jpg", dzImage.ImageName);
                zipFile.AddEntry(fileName, memoryStream);
            }
            var response = new HttpResponseMessage(HttpStatusCode.OK);
            var memStream = new MemoryStream();
            zipFile.Save(memStream); //Null Reference Exception
            response.Content = new ByteArrayContent(memStream.ToArray());
            response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
            response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = string.Format("{0}_images.zip", dzImages.Count()) };
            return response;
        }
    }

zipFile.Save(memStream)はnull参照をスローします。ただし、zipFileもmemStreamもnullではなく、内部例外はありません。したがって、null参照の原因がわかりません。私はWebAPI、メモリストリームの経験がほとんどなく、DotNetZipLibraryをこれまで使用したことがありません。これは、この質問のフォローアップです。30〜50〜3MBのJPEGを確実に返すことができる効率的なASP.NETWebAPIコントローラーが必要です。

何か案は?ありがとう!

4

4 に答える 4

1
public HttpResponseMessage GetItemsInZip(int id)
    {           
            var itemsToWrite = // return array of objects based on id;

            // create zip file stream
            MemoryStream archiveStream = new MemoryStream();
            using (ZipArchive archiveFile = new ZipArchive(archiveStream, ZipArchiveMode.Create, true))
            {
                foreach (var item in itemsToWrite)
                {
                    // create file streams
                    // add the stream to zip file

                    var entry = archiveFile.CreateEntry(item.FileName);
                    using (StreamWriter sw = new StreamWriter(entry.Open()))
                    {
                        sw.Write(item.Content);
                    }
                }
            }

            // return the zip file stream to http response content                
            HttpResponseMessage responseMsg = new HttpResponseMessage(HttpStatusCode.OK);                
            responseMsg.Content = new ByteArrayContent(archiveStream.ToArray());
            archiveStream.Dispose();
            responseMsg.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "test.zip" };
            responseMsg.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip");

            return responseMsg;          
    }

MVC 5 で Framework .NET 4.6.1 を使用

于 2017-07-21T13:46:39.293 に答える