Come è possibile creare un controller API Web che genera e restituisce un file zip compresso in streaming da una raccolta di file JPEG in memoria (oggetti MemoryStream). Sto tentando di usare DotNetZip Library. Ho trovato questo esempio: http://www.4guysfromrolla.com/articles/092910-1.aspx#postadlink. Tuttavia, Response.OutputStream non è disponibile nell'API Web e pertanto la tecnica non funziona. Pertanto ho provato a salvare il file zip in un nuovo MemoryStream; ma ha gettato. Infine, ho provato a utilizzare PushStreamContent. Ecco il mio codice:Utilizzando l'API Web ASP.NET, in che modo un controller può restituire una raccolta di immagini in streaming compresse utilizzando DotNetZip Library?
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) genera riferimento null. Ma né zipFile né memStream sono nulli e non ci sono eccezioni interne. Quindi non sono sicuro di cosa stia causando il riferimento null. Ho poca esperienza con le API Web, i flussi di memoria e non ho mai usato DotNetZipLibrary in precedenza. Questo è il seguito di questa domanda: Want an efficient ASP.NET Web API controller that can reliably return 30 to 50 ~3MB JPEGs
Qualche idea? Grazie!
Non vedo niente di sbagliato con il codice WebAPI. Tuttavia, utilizzerei StreamContent anziché ByteArrayContent. Mi rendo conto che hai detto di ottenere il riferimento null al file zipFile.Save, ma proverei a rimuovere use() attorno al nuovo ZipFile(). –
Grazie. Purtroppo rimuovere l'utilizzo non ha aiutato. Getti ancora NullReferenceException su zipFile.Save (...). Ecco la traccia: at Ionic.Zlib.ParallelDeflateOutputStream._Flush (Boolean lastInput) in Ionic.Zlib.ParallelDeflateOutputStream.Close() in Ionic.Zip.ZipEntry.FinishOutputStream (Stream s, CountingStream entryCounter, Stream encryptor, Stream compressore, CrcCalculatorStream output) in Ionic.Zip.ZipEntry._WriteEntryData (Stream s) a Ionic.Zip.ZipEntry.Write (Stream s) a Ionic.Zip.ZipFile.Save() a Ionic.Zip.ZipFile.Save (Stream outputStream) – CalvinDale
Dopo aver fatto bitmap.Save, cosa è la posizione di memoryStream? Potrebbe essere necessario impostare memoryStream.Position = 0 altrimenti si potrebbero memorizzare zero byte nel file zip. –