I am making an API call that should return a list of PNGs . I’m storing the PNG in blob storage and I’m able to successfully grab them. In the past when I’ve only had to return one image, I’d convert the blob to a memory stream and just handle the memory stream on the client side. That does not seem to work for multiple files though.
[HttpGet("getThumbnails/{seriesId}")]
public async Task<ActionResult<List<MemoryStream>>> GetThumbnails(string seriesId)
{
var pngs = await _service.LoadPNGsMs(seriesId);
Response.ContentType = "image/png ";
return pngs;
}
public async Task<List<MemoryStream>> LoadPNGsMs(string seriesID)
{
var returnList = new List<MemoryStream>();
var blobls = await _azureBlobStorageService.GetBlockBlob(seriesID);
foreach (var blob in blobls)
{
var stream = new MemoryStream();
await blob.DownloadToStreamAsync(stream);
stream.Position = 0;
returnList.Add(stream);
}
return returnList;
}
public async Task<List<CloudBlockBlob>> GetBlockBlob(string seriesID)
{
var blobFiles = containerClient.GetBlobs(prefix: seriesID);
var blobFilePaths = blobFiles.Select(x => x.Name).ToList();
List<CloudBlockBlob> cloudBlockBlobs = new List<CloudBlockBlob>();
foreach (var blob in blobFilePaths)
{
CloudBlockBlob blockBlob = blobContainer.GetBlockBlobReference(blob);
bool isExists = await blockBlob.ExistsAsync();
if (isExists)
cloudBlockBlobs.Add(blockBlob);
}
return cloudBlockBlobs;
}
I am getting a 406 for running this code. Am I doing too much setting the response type to be image/png
? Should I just work with the blobs and forget about the memory streams? I’ll keep playing around with this here and post results if I find anything.
2
Answers
Instead of using
List<MemoryStream>
use aIEnumerable<byte[]>
and write each blob to byte arrays. Your client won’t be able to use the memory stream for multiple blobs in the same way you probably wrote it out to the response for a single item. I would also change it topublic async Task<ActionResult<IEnumerable<byte[]>>> GetThumbnails(string seriesId)
so you can
yield return byte[]
and improve the throughput to the client with less memory consumption on the server overall.Well, you could say use a repeater, and simple then push out the image to the repeater for the number of pictures.
So if I have a table of pictures, then I want the picture name, and then the byte-stream of each picture.
So, this markup:
(nothing special).
but, in above is a plain jane image control.
So, code to load is this:
And row item data bound is where we push out the byte array to each image.
And the result is this:
So, if you have some type of repeater, listview, grid view, datalist view or repeater?
Then just push out the byte array to the image control as a base64 string.
Above is not only simple, but requires no special image handler’s and all that jazz.
You do however, need the mine type.