Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

When I try to display a byte[] array image inside a Details page template using:

public FileContentResult RenderPhoto(byte[] photo)
{
    // var array = (byte[])Session["photo"];
    // return File(array, "image/jpeg");

    return File(photo, "image/jpeg");
}

<img src="@Url.Action("RenderPhoto", Model.Photo)"/>

photo is null.

If I store student.Photo in Session:

//
// GET: /Student/Details/5

public ViewResult Details(int id)
{
    Student student = db.Students.Find(id);

    Session["photo"] = student.Photo;

    return View(student);
}

and try to display the image retrieving the value from Session (commented lines above) it works.

Why I'm getting a null value in the first case?

After passing student to the View in ViewResult Details(int id), Model.Photo doesn't hold that value anymore?

share|improve this question
add comment

2 Answers 2

up vote 10 down vote accepted

Why I'm getting a null value in the first case?

You cannot pass a byte array to the server in an <img> tag. The <img> tag simply sends a GET request to the designated resource. The correct way to do this is to use an id:

<img src="@Url.Action("RenderPhoto", new { photoId = Model.PhotoId })" />

and then:

public ActionResult RenderPhoto(int photoId)
{
    byte[] photo = FetchPhotoFromDb(photoId);
    return File(photo, "image/jpeg");
}
share|improve this answer
    
if I do this I'll query the database just to get the photo. I already have the photo when I load student in the Details ViewResult method. –  Leniel Macaferi Apr 21 '11 at 6:00
    
I'm starting to think of implementing this in a different way. I'll have a model to represent a Photo (a table in the DB). I'll then create a relationship between Student and Photo. This way this scenario will make more sense. Student will have a PhotoId field that I'll use to query the DB. –  Leniel Macaferi Apr 21 '11 at 6:10
add comment

First of all

Url.Action("RenderPhoto", Model.Photo)

Will not work, Model.Photo (presumably your byte array) will be treated as an Object to infer route values of. It'll generate a route with the public properties of an Array object, probably along the lines of

?IsFixedSize=true&IsReadOnly=false&Length=255

That is going to be a pretty unhelpful url. Once the page loads in the browser, the browser will request that image, calling your RenderPhoto method, but there is no parameter called photo, so binding would fail, and even if there was a parameter called photo there (AFAIK) no logic in the DefaultModelBinder for creating a byte array from a string, hence photo is null.

What you need to do is pass an anonymous object with an Id property into Url.Action

Url.Action("RenderPhoto", new { Id = Model.PhotoId })

That will be converted to a querystring possibly along the lines of the following (but it depends on your routes)

/xxx/RenderPhoto/25

And you then need to retreive the data for the photo in your RenderPhoto method

Martin

share|improve this answer
    
that's it man. I was getting something like that string you posted above with the public properties of the array object. As I said I'll implement it in a different way so that I do not have to go to the database one more time just to get the photo. Student will have only the PhotoId and not the Photo itself. –  Leniel Macaferi Apr 21 '11 at 6:19
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.