Friday, November 7, 2014

How to read Image from Database with MVC

Even thou I was finding solutions on the Internet that were not really great at explaining how to make this work, I've come up with a bit different solution, it works perfectly fine for me and It does what I've intended to do. So...

My intention was that, when an administrator creates a new product, that he/she want to have in the database, he/she has an option to add a picture to that product. So my database table is called Product. And it consists of the following columns:

ID - Name - Category - Type - Description - Price - Picture

All of these are irrelevant except the Picture column. Since I wanted to store in the Picture column for each of the product a location where the file is being stored. Which...well  it gave me problem when later on reading it in the View of MVC architecture. For a couple of reasons.

First, when I use Path class to keep a file location, it writes the location into database with \\ slash. This is a problem since on the View, when we are listing products, the <img> tag receives the address using slashes in this / direction. I do not know if this is really what made me a problem, tho It worked only when I used / on the path of "~/Pictures/picture_name01.jpg". If I have done the "~\Pictures\picture_name01.jpg" I  got no result back. 

And that made me wonder, to look into what is written in my database. And guess what? It was C:\Users\Bla1\Bla2|Bla3\App\Pictures\picture_name01.jpg. As I was researching if this can work it was very confusing for me when people say to use in the <img> tag and address @Url.Content(Model.Class). Since the minute I write Model and hit dot, there is no class these people tend to use and I have defined as well. Seeing that some of the code they write in the Content method was also converting a byte characters and using some funky and tricky lines of code I do not see nor understand how they are related to what I wanted to achieve, I've come to this solution.

I thought to give the <img> tag address of the folder where I am storing the Pictures. So my <img tag looks like this:

<img src="~/Pictures/" alt="Image"/>

I've added after the Pictures/picture_name01.jpg to check if it works and it does. So I thought "can I somehow add to this ~/Pictures/ how to locate the file name of the product? And then I thought "and why not save in the database just the file name?" Which I did.

Then I've changed in Action of Controller for my Product where I am creating the products, to save a filename instead of whole path where is being saved. I went to View and wrote next on my <img> tag:

<img src="@Url.Content("~/Pictures/" + @Html.DisplayTextFor(modelItem=>item.Picture)) alt="Image"/>

If you wonder how I come up with this, I've had to check what does the Content method do. When I realized it receives the exact location of the file, it was common sense to add the path to the folder and + to it the Text for the item that is being stored in a database. What you get originally in the MVC default index view's it is @Html. Display For () which basically just displays what you have on your Entity Model, DisplayTextFor converts it to a more "useful" text than just displaying.

Basically what it does on my application is - when administrator creates new Product and adds a picture to it, the picture file (aka picture_name01.jpg) is being saved to the folder called Pictures. The file name is being saved to the database, meaning just the text of the name of the file. And in the View we just read the Folder path and add to it name of the image that is saved in database for each of the Products.

I hope this post will be helpful to others who are beginning with MVC as I am. I really love MVC so far and most probably I will continue making web-applications in the future. Have fun!