Leon Cullens
Leon Cullens

Reputation: 12476

How to return multiple images from controller method?

I have an ASP.NET MVC controller that generates images (they are stored in memory, I don't want to store them on the hard drive) and should return them to my view.

The problem is: I don't how know how to return multiple images from one controller method (I want to show the images in 1 view). I know that I can return a single image with the FileResult for example, but I can't find out (not on google/stackoverflow) how to return multiple images from the same method. Splitting the method up in multiple methods can't be done. Oh, all of the images are converted to a byte[], but that can be reversed if necessary.

Upvotes: 4

Views: 4218

Answers (5)

Tieson T.
Tieson T.

Reputation: 21191

If you have access to the MIME type of the image, you could always render them as Base64-encoded images, instead of making another request to a different controller method. This is a view model I use:

public class ImageViewModel
{
    public string FileName { get; set; }

    public string MIME { get; set; }

    public byte[] Data { get; set; }

    public override string ToString()
    {
        return string.Format(@"data:{0};base64,{1}", MIME.ToLower(), Convert.ToBase64String(Data));
    }
}

You can use the Filename property in the alt attribute of the <img /> tag, so the markup & model-binding in your view would look something like this (assuming Razor syntax):

<img src="@model.ToString()" alt="@model.FileName" />

You do lose image-caching, AFAIK - that hasn't been an issue for me, but is understandably a deal-breaker for some.

Upvotes: 4

lahsrah
lahsrah

Reputation: 9173

This should work. Note I am reading my images from disk for my example but they can come from memory or anywhere. Then on the client side use java-script to display them.

[HttpGet]
public JsonResult Images()
{
    var image1Base64 = Convert.ToBase64String(System.IO.File.ReadAllBytes(Server.MapPath("~/Images/1.jpg")));
    var image2Base64 = Convert.ToBase64String(System.IO.File.ReadAllBytes(Server.MapPath("~/Images/2.jpg")));

    var jsonResult = Json(new { image1 = image1Base64, image2 = image2Base64 }, JsonRequestBehavior.AllowGet);
    jsonResult.MaxJsonLength = int.MaxValue;

    return jsonResult;
}

Upvotes: 5

SynerCoder
SynerCoder

Reputation: 12766

You wish to show multiple images based on input of the user, but don't want to save to the hard disk (chat). Therefor I recommand you using a session variable to save the users input in. And the use a simple FileResult to return multiple images based on that session variable.

http://blog.theobjectguy.com/2009/12/session-with-style.html

Upvotes: 1

Sleiman Jneidi
Sleiman Jneidi

Reputation: 23329

I think that you can solve it in another way, instead of returning multiple images, you can create a utility method that loads the image in the controller

public FileContentResult GetImage(int imageId)
{
  var image = GetImageById(imageId); // get from a list for example
  return File(image, "image/jpeg"); // your image Mime type
}

and in the View you can do the following, iterate over the images

@foreach (var image in Model)
{ 
<img alt="" src="@Url.Action("GetImage", "ControllerName", new {imageId =image.Id})"/>
}

Upvotes: 3

terjetyl
terjetyl

Reputation: 9565

If your requirement is to show multiple images in one view it would be easier to use 2 action methods. One that returns a image with FileResult and another where you just use standard html img tags pointing the first action method

Upvotes: 0

Related Questions