I have a table in the db, which has the following :- CountryID, CountryName, and CountryImage.
Now I am trying to display the image in the index and I have the following in the View :-
<td>
#if (item.Image != null)
{
<img src="#Model.GetImage(item.Image)" alt="#item.CountryName"/>
}
and then in the ViewModel I have :-
public FileContentResult GetImage(byte[] image)
{
if (image != null)
return new FileContentResult(image, "image/jpeg");
else
{
return null;
}
}
However I cannot see the image properly.
What am I doing wrong?
Thanks in advance for your help and time
UPDATE
Ok So I have implemented the following in the View :-
<td>
#if (item.Image != null)
{
<img src="#Url.Action("GetImage", "CountryController", new { id = item.CountryID })" alt="#item.CountryName" />
}
</td>
and in the CountryController :-
public ActionResult GetImage(int id)
{
var firstOrDefault = db.Countries.Where(c => c.CountryID == id).FirstOrDefault();
if (firstOrDefault != null)
{
byte[] image = firstOrDefault.Image;
return File(image, "image/jpg");
}
else
{
return null;
}
}
but when I try to debug the code, the ActionResult GetImage is not being hit
Two possibilities.
Write a controller action instead which given an image id will return this image:
public ActionResult GetImage(int id)
{
byte[] image = ... go and fetch the image buffer from the database given the id
return File(image, "image/jpg");
}
and then:
<img src="#Url.Action("GetImage", "SomeController", new { id = item.Id })" alt="#item.CountryName" />
Obviously now in your initial model you don't need the Image property. This will be retrieved subsequently in the controller action responsible for that.
Another possibility is to use data URI scheme to embed the images as base64 strings but it might not be widely supported by all browsers:
<img src="data:image/jpg;base64,#(Convert.ToBase64String(item.Image))" alt="#item.CountryName" />
You don't need a controller action in this case as the images are directly embedded into your markup as base64 strings.
Related
I'm uploading an image to a folder images. it's working fine.but what I actually want is to look for a folder name (I have the folder name) if not found create that folder and give it that name.how could that happen?
this is what I have done so far:
string ImageName = System.IO.Path.GetFileName(file.FileName);
string physicalPath = Server.MapPath("~/images/" + ImageName);
instead of images I should have folderName.
the complete view:
#{
ViewBag.Title = "Index";
}
#using (Html.BeginForm("FileUpload", "datum", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
<div>
category<br />
#Html.DropDownList("category", ViewBag.Roles as SelectList)
<br/>
description<br />
#Html.TextBox("description") <br />
Image<br />
<input type="File" name="file" id="file" value="Choose File" />
<input type="submit" value="Upload" class="submit" />
</div>
}
the complete controller
public class datumController : Controller
{
DataEntry db = new DataEntry();
public ActionResult Index()
{
var data = from p in db.categories
select p.categoryName;
SelectList list = new SelectList(data);
ViewBag.Roles = list;
return View();
}
public ActionResult create ()
{
return View();
}
[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase file)
{
if (file != null)
{
string ImageName = System.IO.Path.GetFileName(file.FileName);
string physicalPath = Server.MapPath("~/images/" + ImageName);
// save image in folder
file.SaveAs(physicalPath);
//save new record in database
datum newRecord = new datum();
newRecord.category = Request.Form["category"];
newRecord.description = Request.Form["description"];
newRecord.imagePath = ImageName;
db.data.Add(newRecord);
db.SaveChanges();
}
//Display records
return RedirectToAction("Display");
}
so I should be getting the selected value from the drop down list and attach it to the physical path, check if folder exists if no then create folder and upload image to that folder
Try like below...
string subPath ="ImagesPath"; // your code goes here
bool exists = System.IO.Directory.Exists(Server.MapPath(subPath));
if(!exists)
System.IO.Directory.CreateDirectory(Server.MapPath(subPath));
For further info, please refer below link.
If a folder does not exist, create it
if (file != null && file.ContentLength > 0)
{
string path = Path.Combine(Server.MapPath("~/Images"), Path.GetFileName(file.FileName));
tbl_MixEmp.EmpImage = Path.Combine("~/Images", file.FileName);
file.SaveAs(path);
}
I am going to include the code how I have it. I felt like what I had should work because I got no squiggly lines. lol But I end up with a Redirect Loop.
First off I got the basic implementation from Nadeem Afana's blog. I don't think the CultureHelper.cs or the BaseController.cs may be needed to implement a returnUrl functionality, but since they are part of the code I am including them here so that you don't have to dig through his website to look for it. I have tried to eliminate scrolling for you as well.
HERE IS MY CODE:
Helpers/CultureHelper.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
namespace xxxUSA.Helpers
{
public static class CultureHelper
{
// Valid cultures REMOVED SOME CODES FOR BREVITY
private static readonly List<string> _validCultures = new List<string>
{ "en-AU", "en-BZ", "en-CA", "en-029", "en-IN", "en-IE", "en-JM",
"en-MY", "en-NZ", "en-PH", "en-SG", "en-ZA", "en-TT", "en-GB",
"en-US", "en-ZW", "es-CR", "es-DO", "es-EC", "es-SV", "es-GT",
"es-HN", "es-MX", "es-NI", "es-PA", "es-PY", "es-PE", "es-PR",
"es-ES", "es-US", "es-UY", "es-VE" };
private static readonly List<string> _cultures = new List<string> {
"en-US", // first culture is the DEFAULT
"es", // Spanish NEUTRAL culture
"ar" // Arabic NEUTRAL culture
};
public static bool IsRightToLeft()
{
return
System.Threading.Thread.CurrentThread
.CurrentCulture.TextInfo.IsRightToLeft;
}
public static string GetImplementedCulture(string name)
{
// make sure it's not null
if (string.IsNullOrEmpty(name))
return GetDefaultCulture(); // return Default culture
if (_validCultures.Where(c => c.Equals(name,
StringComparison.InvariantCultureIgnoreCase)).Count() == 0)
return GetDefaultCulture(); // return Default if invalid
if (_cultures.Where(c => c.Equals(name,
StringComparison.InvariantCultureIgnoreCase)).Count() > 0)
return name; // accept it
var n = GetNeutralCulture(name);
foreach (var c in _cultures)
if (c.StartsWith(n))
return c;
return GetDefaultCulture(); // return Default if no match
}
public static string GetDefaultCulture()
{
return _cultures[0]; // return Default culture
}
public static string GetCurrentCulture()
{
return Thread.CurrentThread.CurrentCulture.Name;
}
public static string GetCurrentNeutralCulture()
{
return GetNeutralCulture(Thread.CurrentThread.CurrentCulture.Name);
}
public static string GetNeutralCulture(string name)
{
if (name.Length < 2)
return name;
return name.Substring(0, 2);
}
}
}
Controllers/BaseController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using xxxUSA.Helpers;
namespace xxxUSA.Controllers
{
public class BaseController : Controller
{
protected override IAsyncResult BeginExecuteCore(
AsyncCallback callback, object state)
{
string cultureName = null;
// Attempt to read the culture cookie from Request
HttpCookie cultureCookie = Request.Cookies["_culture"];
if (cultureCookie != null)
cultureName = cultureCookie.Value;
else
cultureName = Request.UserLanguages != null &&
Request.UserLanguages.Length > 0 ? Request.UserLanguages[0]
: null; // obtain it from HTTP header AcceptLanguages
// Validate culture name
cultureName = CultureHelper.GetImplementedCulture(cultureName);
// Modify current thread's cultures
Thread.CurrentThread.CurrentCulture = new
System.Globalization.CultureInfo(cultureName);
Thread.CurrentThread.CurrentUICulture =
Thread.CurrentThread.CurrentCulture;
return base.BeginExecuteCore(callback, state);
}
}
}
OK, now we get into where I have modified some things. I will comment on anything I added
Controllers/HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using xxxUSA.Helpers;
using xxxUSA.Models;
namespace xxxUSA.Controllers
{
public class HomeController : BaseController
{
ApplicationDbContext _db = new ApplicationDbContext();
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
return View();
}
public ActionResult Contact()
{
return View();
}
//I ADDED THIS LAST PARAMETER
public ActionResult SetCulture(string culture, string returnUrl)
{
// Validate input
culture = CultureHelper.GetImplementedCulture(culture);
// Save culture in a cookie
HttpCookie cookie = Request.Cookies["_culture"];
if (cookie != null)
cookie.Value = culture; // update cookie value
else
{
cookie = new HttpCookie("_culture");
cookie.Value = culture;
cookie.Expires = DateTime.Now.AddYears(1);
}
Response.Cookies.Add(cookie);
//THIS WORKS
return Redirect(returnUrl);
//THIS DOES NOT
if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
Now for the code on the Home Page
Views/Home/Index.cshtml
#{
var culture = System.Threading.Thread.CurrentThread
.CurrentUICulture.Name.ToLowerInvariant();
ViewBag.Title = culture;
}
//I ADDED THIS LAST PARAMETER
#helper selected(string c, string culture, string returnUrl)
{
if (c == culture)
{
#:checked="checked"
}
}
#using (Html.BeginForm("SetCulture", "Home"))
{
#Resources.ChooseYourLanguage
<input name="culture" id="en-us" value="en-us"
//I ADDED THIS LAST PARAMETER "About"
type="radio" #selected("en-us", culture, "About") /> English
<input type="Hidden" name="returnUrl" value="About" />
<input name="culture" id="es" value="es"
//I ADDED THIS LAST PARAMETER "About"
type="radio" #selected("es", culture, "About") /> Español
}
//LOTS OF STUFF LOADS HERE LIKE RESOURCE REFERENCES, GRAPHICS, CONTENT,
//NOT IMPORTANT FOR THE IMPLEMENTATION REMOVED FOR BREVITY
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
(function ($) {
$("input[type = 'radio']").click(function () {
$(this).parents("form").submit(); // post form
});
})(jQuery);
</script>
}
So the reason I added the "About" was so if I got it to work, It would redirect to the "About" Action instead of back to the same homepage. It doesn't work though.
Can I not overload the checkboxes #Selected Method the way I have?
Also, NOT IMPORTANT NOW, but what if I wanted to add this to other views from other controllers, Could I include another parameter to designate the controller and action it needs to return to so that I don't have to repeat the code in each controller?
I have contacted Nadeem on twitter and he said he would check it out and try and help. I really appreciate his work and seems like a very kind fellow.. Thanks in advance for simply helping in any capacity!
OK so I have a products/Ingredients page where I have stuff coming from the database, here how I hacked that to show the right field from the database. This is a total HACK BEWARE.
Views/Products.cshtml
#model IEnumerable<xxxUSA.Models.Ingredient>
#{
var culture = System.Threading.Thread.CurrentThread
.CurrentUICulture.Name.ToLowerInvariant();
ViewBag.Title = culture;
}
#helper selected(string c, string culture)
{
if (c == culture)
{#:checked="checked"}
}
<div class="row">
<div class="large-12 columns">
#using(Html.BeginForm("SetCulture", "Ingredient"))
{
<div class="row">
<div class="large-6 columns">
<label>#Resources.ChooseYourLanguage</label>
<input type="Hidden" name="returnUrl" value="/Prodcuts/" />
<input name="culture" id="en-us" value="en-us" type="radio"
#selected("en-us", culture) /> English
<input name="culture" id="es" value="es" type="radio"
#selected("es", culture) /> Español
</div>
</div>
}
#{ViewBag.Culture = System.Threading.Thread.CurrentThread
.CurrentUICulture.Name.ToLowerInvariant();}
//Here is where the conditional logic hack I use to show one field
//or another from the database based on culture
#if (ViewBag.Culture == "en-us") {
#Html.DisplayFor(modelItem => item.IngredientNameEn)
} else {
#Html.DisplayFor(modelItem => item.IngredientNameEs) }
Basically using that conditional logic anywhere I have data that has a spanish or english version. it's hacky as hell though.
Try this:
public ActionResult SetCulture(string culture, string returnUrl)
{
// Validate input
culture = CultureHelper.GetImplementedCulture(culture);
// Save culture in a cookie
HttpCookie cookie = Request.Cookies["_culture"];
if (cookie != null)
cookie.Value = culture; // update cookie value
else
{
cookie = new HttpCookie("_culture");
cookie.Value = culture;
cookie.Expires = DateTime.Now.AddYears(1);
}
Response.Cookies.Add(cookie);
if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
I'm also using Nadeem's i18n solution in a project. The way you switch the culture in this project is through clicking on flags (anchor tags in image tags). I added a returnUrl and ended up with a redirect loop. To fix the redirect loop issue, I made a few changes to the code and ended up with this code:
File: BaseController.cs (added this method)
public ActionResult SetCulture(string culture, string returnUrl)
{
// Validate input
culture = CultureHelper.GetImplementedCulture(culture);
RouteData.Values["culture"] = culture;
// Save culture in a cookie
HttpCookie cookie = Request.Cookies["_culture"];
if (cookie != null)
{
// update cookie value
cookie.Value = culture;
}
else
{
cookie = new HttpCookie("_culture");
cookie.Value = culture;
cookie.Expires = DateTime.Now.AddYears(1);
}
Response.Cookies.Add(cookie);
return Redirect(returnUrl);
}
File: _layout.cshtml (flags for selecting culture):
#{ var daDkUrl = Url.Action("setculture", "base", new { culture = "da-DK", returnUrl = Request.RawUrl }); }
<a href="#daDkUrl">
<img src="~/content/images/flag_da.gif" width="16" height="11" alt="Dansk" />
</a>
|
#{ var enUsUrl = Url.Action("setculture", "base", new { culture = "en-US", returnUrl = Request.RawUrl }); }
<a href="#enUsUrl">
<img src="~/content/images/flag_en.gif" width="16" height="11" alt="English" />
</a>
Finally, ensure your controllers inherit from BaseController.cs.
public class TestController : BaseController
{
//Code
}
How to store Image in Database and then retrieve and display it using MVC
I am Using MVC3, Entity Framework Database First, and SQL SERVER 2008
In Database I have used varbinary(MAX) for the Image
Image varbinary(MAX) Checked
Further I used
[DisplayName("Image")]
public byte[] Image { get; set; }
in my mapping class
When I tried to save it in my Create action method
public ActionResult Create(MarjaaModel newMarjaa, HttpPostedFileBase uploadFile)
{
if (uploadFile != null && uploadFile.ContentLength > 0)
{
newMarjaa.Image = new byte[uploadFile.ContentLength];
uploadFile.InputStream.Read(newMarjaa.Image, 0, uploadFile.ContentLength);
}
try
{
data.submitMarjaa(newMarjaa);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
I am successful in saving the image as binary data
But please tell me how I can retrieve this image and display it in my View
Finally I did it
A simple method in my controller
public ActionResult ShowImage(long id)
{
var model = data.getMarjaa(id);
return File(model.Image, "image/jpg");
}
and In my View
<td>
#if (item.Image == null)
{
<img width="40" height="40" src="http://www.abc.com/images/staff/no_worry[1].jpg" />
}
else
{
<img width="40" height="40" src='#Url.Action("ShowImage", "Admin", new { id = item.id })' />
}
</td>
<td>
#{
var base64 = Convert.ToBase64String(item.NewsImage);
var imgsrc = string.Format("data:image/jpg;base64,{0}", base64);
}
<img src='#imgsrc' style="max-width:100px;max-height:100px" />
</td>
only this need to view the pics
I am a beginner in asp mvc 3, and i develop an application ,
I first want to describe my application
so i have in my database , a table account and a table role and the relation ship between account and role is many to many, so i have a association table account_role,
i work with Entity Framework database first and i generate my POCO with EF DbContext Generator,
i want ann edit Account page dispay a chekbox of Roles
this is my code
Controller Account
public ActionResult Edit(int id)
{
accounts accounts = db.accounts
.Include(i => i.roles_accounts)
.Where(i => i.id_account == id)
.Single();
PopulateAssignedRoleData(accounts);
return View(accounts);
}
// populate Assigned RoleDATA pour afficher les checkbox
private void PopulateAssignedRoleData(accounts account)
{
//Get all role
var allRole =db.roles;
//For each role, the code checks if the role exists in the property of accountRole
// To create effective search when checking if a role is assigned to the account,
// assigned roles in are put into a collection HashSet
var accountRoles = new HashSet<int>(account.roles_accounts.Select(r => r.id_account_role));
var viewModel = new List<AssignedRoleData>();
// Property Assigned role of which is allocated account is set to true.
//The view will use this property to determine
//what check boxes to be displayed as selected.
//Finally, the list is passed to the view in a ViewBag
foreach (var role in allRole)
{
viewModel.Add(new AssignedRoleData
{
RoleId = role.id_role,
Name = role.name,
Assigned = accountRoles.Contains(role.id_role)
});
}
ViewBag.roles = viewModel;
}
//
// POST: /Account/Edit/5
[HttpPost]
public ActionResult Edit(int id, FormCollection formCollection, string [] selectedRoles)
{
var accountsToUpdate = db.accounts
.Include(i => i.roles_accounts)
.Where(i => i.id_account == id)
.Single();
if (TryUpdateModel(accountsToUpdate, "", null, new string[] { "roles_accounts" }))
{
try
{
if (String.IsNullOrWhiteSpace(accountsToUpdate.login))
{
accountsToUpdate.roles_accounts = null;
}
UpdateAccountRole(selectedRoles, accountsToUpdate);
db.Entry(accountsToUpdate).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
catch (DataException)
{
ModelState.AddModelError("", "Unable to save change");
}
}
PopulateAssignedRoleData(accountsToUpdate);
return View(accountsToUpdate);
}
// update AccountRole (liste of checkbox)
private void UpdateAccountRole(string[] selectedRoles, accounts accountToUpdate)
{
if (selectedRoles == null)
{
accountToUpdate.roles_accounts=new List<roles_accounts>();
return;
}
var selectedRolesHS = new HashSet<string>(selectedRoles);
var accountsRoles = new HashSet<int>
(accountToUpdate.roles_accounts.Select(r => r.id_account_role));
foreach(var role in db.roles_accounts)
{
if( selectedRolesHS.Contains(role.id_account_role.ToString()))
{
if(!accountsRoles.Contains(role.id_account_role))
{
accountToUpdate.roles_accounts.Add(role);
}
}
else
{
if (accountsRoles.Contains(role.id_account_role))
{
accountToUpdate.roles_accounts.Remove(role);
}
}
}
}
And i create a folder nammed ViewModels, and in this folder i create a classe AssignedRoleData To provide data to the view for the list of check boxes,
this is the AssignedRoleData
public class AssignedRoleData
{
public int RoleId { get; set; }
public string Name { get; set; }
public bool Assigned { get; set; }
and in the Edit.schtml
i put this code
<div class="editor-field">
<table>
<tr>
#{
int cnt = 0;
List<App_ERP1.ViewModels.AssignedRoleData> roles=ViewBag.roles;
foreach (var role in roles) {
if (cnt++ % 3 == 0) {
#: </tr> <tr>
}
#: <td>
<input type="checkbox"
name="selectedRoles"
value="#role.RoleId"
#(Html.Raw(role.Assigned ? "checked=\"checked\"" : "")) />
#role.RoleId #: #role.Name
#:</td>
}
#: </tr>
}
}
}
My Problem is the checkbox does not retain its state and also each time when I click the save button it removes the added roles (choose)
thanks to help me
you need to use a "for" instead of the "foreach" on the view and your attribute "name" probably needs to be something like name="selectedRoles[i]" . Tip: Don't access the database directly on the controller. Create a middle layer where you have the class AccountRoleService and here put the logic and then create another layer for accessing the database called repository (e.g AccountRoleRepository) where you actually do your LINQ to SQL stuff. If you want to reuse methods will be much easier. So controllers do little and call service classes. Service classes do logic and call repository classes to access the database. So if you want to unit test the services you will be on the right path.
for (i = 0; i< roles.Count, i++) {
if (cnt++ % 3 == 0) {
#: </tr> <tr>
}
#: <td>
<input type="checkbox"
name="selectedRoles[" + i + "]"
value="#role.RoleId"
#(Html.Raw(role.Assigned ? "checked=\"checked\"" : "")) />
#role.RoleId #: #role.Name
#:</td>
}
#: </tr>
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:
After I have press the "Save" button on the view, the HttpPostedFileBase object is not null.
After I call the db.SaveChanges() method, one row is added in database's table.
When I call the GetImage, it doesn't return null.
But on the view, there's not image displayed
Thanks for helping
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;
}
}
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.
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
}
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.
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;}
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
}
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...
Simple Open the Products.cs file in your entities folder and change
public byte ImageData {get;set;}
To:
public byte[] ImageData{get;set;}