Richard77
Richard77

Reputation: 21661

ASP.NET MVC3: upload image and save it to database

I am working on Steven Sanderson's book (Pro ASP.NET MVC 3). I am on p. 294. I've copied word per word what's in the book but it is not working.

This is the action method

public ActionResult Edit(Product product, HttpPostedFileBase image)
{
  if(ModelState.IsValid)
  {
    if(image != null)
    {
      product.ImageMimeType = image.ContentType;
      product.ImageData = new byte[image.ContentLength];
      image.InputStream.Read(product.ImageData, 0, image.ContentLength); 
    }

    //...Save product in the database using Entity Framework
  }
}

This is how to display the image on the razor page

<img width="150" height="150"
  src = "@Url.Action("GetImage", "Home", new { Model.ProductID })" /> 

And finally, the GetImage

public FileContentResult GetImage(int productID)
    {
        Product prod = repository.Products.FirstOrDefault(p => p.ProductID == productID);
        if (prod != null)
        {
            return File(prod.ImageData, prod.ImageMimeType);
        }
        else
        {
            return null;
        }
    }

EDIT

I have followed the whole process (while debugging) from the beginning to the end and this is what I can say:

Upvotes: 2

Views: 14127

Answers (8)

Salem Kosemani
Salem Kosemani

Reputation: 101

Simple Open the Products.cs file in your entities folder and change

public byte ImageData {get;set;}

To:

public byte[] ImageData{get;set;}

Upvotes: 0

DiegoS
DiegoS

Reputation: 1

the problem is in Action method.. it should be you has to change de name of the Controller... "GetImage" function is in "Admin" Controller.. The rest of the code is fine...

Upvotes: 0

Ricardo Ruiz Romero
Ricardo Ruiz Romero

Reputation: 155

I run into the same problem.. try this:

public ActionResult Edit(Product product, HttpPostedFileBase image)
{
  if(ModelState.IsValid)
  {
     if(image != null)
     {
       product.ImageMimeType = image.ContentType;
       product.ImageData = new byte[image.ContentLength];

       iname.InputStream.Position = 0; // This is what makes the difference

       image.InputStream.Read(product.ImageData, 0, image.ContentLength); 
     }

//...Save product in the database using Entity Framework

}

Upvotes: 0

Darren
Darren

Reputation: 1

Even simpler resolution is to just change the following line in your product class:

change from:

public byte ImageData {get;set;}

To:

public byte[] ImageData{get;set;}

Upvotes: 0

LadyRoot
LadyRoot

Reputation: 81

I had the same problem, too. Just change the part of Edit method in controller to sth like this:

 if (image != null)
            {
                mvcImages img = db.mvcImages.Where(p => p.p_id == prod.p_id).FirstOrDefault();
                prod.p_imageMimeType = image.ContentType;
                byte[] buffer = new byte[image.ContentLength];
                image.InputStream.Read(buffer, 0, image.ContentLength);
                prod.p_imageData = buffer;
                img.p_imageMimeType = prod.p_imageMimeType;
                img.p_imageData = prod.p_imageData;
                db.SaveChanges();
            }

That works fine. Also remember to save changes within the same brackets as your "if" command.

Upvotes: 0

Tieson T.
Tieson T.

Reputation: 21239

Modify your action method like so:

<img width="150" height="150" src = "@Url.Action("GetImage", "Home", new { @id = Model.ProductID })" /> 

Other than that small difference (adding the id parameter), your code is very similar to mine, and my images load just fine. BTW, if you look at the HTML source for your page, do you see:

/GetImage/<some number here>

or

/GetImage/

as the value of your src attribute? If the latter, this should definitely fix the problem. If the former, you may need to enable GET requests.

Upvotes: 1

LaserBeak
LaserBeak

Reputation: 3285

Here's the answer to get that Steven Sanderson example working, change your saving procedure as such:

            if (image != null)
            {

                var product = new Product();

                product.FileName = image.FileName; //<- optional filename
                product.ImageMimeType = image.ContentType;
                int length = image.ContentLength;
                byte[] buffer = new byte[length];
                image.InputStream.Read(buffer, 0, length);
                product.ImageData = buffer;

              //Save product to database 

            }

Upvotes: 0

Martin
Martin

Reputation: 11041

File should be FileContentResult since it is bytes and not an actual file on the disk. And img should be prod, correct?

public FileContentResult GetImage(int productID)
{
    Product prod = repository.Products.FirstOrDefault(p => p.ProductID == productID);
    if (prod != null)
    {
        return new FileContentResult(prod.ImageData, prod.ImageMimeType);
    }
    else
    {
        return null;
    }
}

Upvotes: 2

Related Questions