4

I have a view which contains a users id and an image column.

Here's what i've tried doing to retrieve the image but i keep getting a box with an red x instead of the actual image.

View

<td><img src="<%= Url.Action( "DisplayImage" , "User" , new { id = item.id} ) %>" alt="" /></td>

Controller

  public FileContentResult DisplayImage(string id)
    {
        byte[] image = repository.GetImage(id);
        return File(image, "image/jpg");
    }

i've also tried returning an ActionResult instead and that didn't work either.

Repository

    public Byte[] GetImage(string id)
    {

        var image = db.GetImage(id).First<GetImageResult>();

        if (image == null)
            return null;
        return image.UserImage;
    }

LinqTOSQL Class

    [Function(Name="dbo.GetImage")]
public ISingleResult<GetImageResult> GetImage([Parameter(DbType="VarChar(8)")] string id)
{
    IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), id);
    return ((ISingleResult<GetImageResult>)(result.ReturnValue));
}

public partial class GetImageResult
{
    private System.Byte[] _userImage;

    public GetImageResult()
    {
    }


    [Column(Storage="_userImage", DbType="Image")]
    public System.Byte[] UserImage
    {
        get
        {
            return this._userImage;
        }
        set
        {
            if ((this. _userImage!= value))
            {
                this. _userImage = value;
            }
        }
    }
}

I've been killing myself all day trying to get this to work, but it just isn't working. The return type on the stored procedure is an integer (atleast when i look at parameters in SQL Server Management Studio it says integer), but i can't redefine that now can i?

It's actually hitting the DisplayImage Action with the correct parameters within the UserController and returning File(imageByteArray, "image/jpg") but only a box with red x is being displayed. Any help would be greatly appreciated.

edit: I've tried debugging by adding a Reponse.BinaryWrite(imageByteArray) within the action result and hitting the url directly by goign to http://localhost/User/DisplayImage?id=10101010 and the image for that user is displayed in mspaint.

edit2: I also did a view source and my html for that image tag came out as following.

<td>
    <img src='/User.mvc/GetImage?id=U00915441' alt="" />
</td>

Thanks

5
  • I've had a problem like this where it would just try to find the image by path and not from the Route. Have you tried debugging to see if the application goes into the controller? Commented Nov 18, 2009 at 17:49
  • It does hit the controller action DisplayImage(string id) and it goes through it without a problem Commented Nov 18, 2009 at 18:29
  • use fiddler too to see exactly what comes back down the wire Commented Nov 18, 2009 at 19:09
  • It's showing an actual image in the imageview tab in fiddler. When i go to textview it's displaying a weird string which ends with ,ImageMan by Data Techniques, Inc.þ{±¾YÆÎÖ(1$Þ Commented Nov 18, 2009 at 20:05
  • And when i view source in my web browser i'm getting <td> <img src='/User.mvc/DisplayImage?id=0012121' alt="" /> </td> Commented Nov 18, 2009 at 20:07

1 Answer 1

3

Look at this question I had from a while back - the solution was special ActionResult type for images

Edit: Here's my code. I'm actually creating an ImageResult class from an Image that I created with GDI+ like this :

 return new ImageResult()
 {
      ImageFormat = spriteInfo.ImageFormat,
      EncodedImageBytes = spriteInfo.GetImageStream()
 };

The image result class is. You'll notice if I provide an EncodedImageBytes parameter it will send that to the output stream. This looks like exactly what you want. On the other hand if you're just passing in an Image then it will just write that Image out to the output stream.

 public class ImageResult : ActionResult
    {
        public ImageResult() { }
        public int? Quality { get; set; }
        public Image Image { get; set; }
        public ImageFormat ImageFormat { get; set; }
        public byte[] EncodedImageBytes { get; set; }

        public override void ExecuteResult(ControllerContext context)
        {
            // verify properties 
            if (EncodedImageBytes == null)
            {
                if (Image == null)
                {
                    throw new ArgumentNullException("Image");
                }
            }
            if (ImageFormat == null)
            {
                throw new ArgumentNullException("ImageFormat");
            }
            // output 
            context.HttpContext.Response.Clear();

            if (ImageFormat.Equals(ImageFormat.Bmp)) context.HttpContext.Response.ContentType = "image/bmp";
            if (ImageFormat.Equals(ImageFormat.Gif)) context.HttpContext.Response.ContentType = "image/gif";
            if (ImageFormat.Equals(ImageFormat.Icon)) context.HttpContext.Response.ContentType = "image/vnd.microsoft.icon";
            if (ImageFormat.Equals(ImageFormat.Jpeg)) context.HttpContext.Response.ContentType = "image/jpeg";
            if (ImageFormat.Equals(ImageFormat.Png)) context.HttpContext.Response.ContentType = "image/png";
            if (ImageFormat.Equals(ImageFormat.Tiff)) context.HttpContext.Response.ContentType = "image/tiff";
            if (ImageFormat.Equals(ImageFormat.Wmf)) context.HttpContext.Response.ContentType = "image/wmf";

            // output stream
            Stream outputStream = context.HttpContext.Response.OutputStream;
            if (EncodedImageBytes != null)
            {
                outputStream.Write(EncodedImageBytes, 0, EncodedImageBytes.Length);
            }
            else
            {
                ImageUtil.SaveImageToStream(outputStream, Image, ImageFormat, Quality);
            }
        }

    }
Sign up to request clarification or add additional context in comments.

6 Comments

reply back if this doesnt help and ill dig up the code im using. i am actually creating images dynamically and serving them up with no problem - so i'm doing it from a byte stream
Okay i didnt have the ImageUtil.SaveImageToStream function so i commented that out and ran it and i'm still getting the same error. Here's what i did in my Controller var imageResult = new ImageResult(); imageResult.EncodedImageBytes= repository.GetImage(id); imageResult.ImageFormat = ImageFormat.Bmp; return imageResult. I used the same view as i posted earlier and i'm still getting a red x. In fiddler i do see the actual image in the imageview tab, but it's not displaying.
try System.IO.File.WriteAllBytes("test.bmp", bytes) within the action method and then verify you can load that image directly into the browser. look in Fiddler and see whats coming back - including the header. they have an ImageView tab - see if you see anything there. can all browsers load BMP? im not sure about that one. i think so, but check that too. bmp seems a bad format to be using anyway
Okay i did what you said. And it does write the image to a file, but it doesn't display if i try to open the image up with I.E. or Chrome. It does display if i open it up with paint or any other picture application. I also tried changing the image type to jpeg and encountered the same results. In the imageview tab of fiddler i can see the image.
then your problem is not related to MVC. its that the image cant be loaded by the browser. you need to reencode the image as JPG or PNG. since it is already BMP, and only 1712 bytes I'm assuming its not a photo. i'd recommend PNG then. you should encode the image as JPEG into the database. now you said you DID change the image type to jpeg. what do you mean by that? you cant just change content-type if thats what you're trying. you need to get to a point where you can File.WriteAllBytes() and load it in IE before worrying about MVC related issues
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.