Paul
Paul

Reputation: 3142

ASP.NET MVC 3 Preview Image

I'm using MVC 3 and using the AjaxUpload plugin to upload an image using AJAX. I don't want to save the image in the file system, instead save it to the session object and then output the stream to populate an image control on the form? Would anyone know how to do this?

Upvotes: 1

Views: 2212

Answers (3)

SunilK
SunilK

Reputation: 157

Some example code. Modify it to whatever you want to do. Not really a good idea to sling an image into a session if lots of users. Better to stick it into a db if short lived, or if long lived, a more permanent storage (filesystem maybe).

    public ActionResult UploadImage()
    {
        foreach (string imageName in Request.Files)
        {
            HttpPostedFileBase file = Request.Files[imageName];
            if (file.ContentLength > 0)
            {
                BinaryReader br = new BinaryReader(file.InputStream);
                byte[] content = br.ReadBytes(file.ContentLength);
                Session[imageName] = content; // better to store in a db here
            }
        }
        return View();
    }

    // return the image (controller action)  /mycontroller/ViewImage?imageName=whatever
    public FileStreamResult ViewImage(string imageName)
    {
        byte[] content = (byte[])Session[imageName] ; // where ever your content is stored (ideally something other than session)
        MemoryStream ms = new MemoryStream(content);
        return new FileStreamResult(ms, "application/octet-stream"); // set content type based on input image, it might be png, jpg, gif etc.,
    }

Hope this helps.

Upvotes: 1

Darin Dimitrov
Darin Dimitrov

Reputation: 1038720

No idea why would ever want to do that (store the file in session) because if you have lots of users uploading their files at the same time, storing those files in the memory of your web server, especially if those files are big, won't make this server last very long. Storing the file on the filesystem is the recommended approach.

But anyway, here's how you could do it (assuming you didn't read or cared about my previous remark):

[HttpPost]
public ActionResult Upload(MyViewModel model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    var buffer = new byte[model.File.InputStream];
    model.File.InputStream.Read(buffer, 0, buffer.Length);
    Session["uploadedFile"] = buffer;
    return View(model);
}

where the File property on the view models is a HttpPostedFileBase. Next you could have a controller action which will serve this file:

public ActionResult Image()
{
    byte[] buffer = (byte[])Session["uploadedFile"];
    return File(buffer, "image/png");
}

and in the view you will have an <img> tag pointing to this action:

<img src="@Url.Action("image")" alt="" />

Now of course the AjaxUpload plugin allows you to upload the file using AJAX, so you don't need to reload the entire page. So in this case your controller action could simply return a JSON object to indicate whether the upload process succeeded and then in the success callback set the src property of the <img> tag to the controller action that will serve the file.

Upvotes: 4

Artem Koshelev
Artem Koshelev

Reputation: 10607

SomeView.cshtml:

<img src="@Url.Action("/Image/Render")" />

ImageController.cs:

public ActionResult Render() {
   return File((byte[])Session["Avatar"], "image/jpeg")
}

Upvotes: 1

Related Questions