I am storing images as byte arrays inside a SQL database.
Here is my Index method (inside the controller):
public ActionResult Index()
{
var list = db.UserProfiles.ToList();
Dictionary<int, ActionResult> picture = list.ToDictionary(item => item.CarID, item => CarPic(item.Picture));
ViewBag.CarPictures = picture;
return View(list);
}
Here is my CarPic method:
public ActionResult CarPic(byte[] imageBytes)
{
return imageBytes == null ? null : File(imageBytes, "image/jpeg");
}
Here is how I am trying to display the image inside my view:
foreach(var item in Model)
{
<img src="#ViewBag.CarPictures[item.CarID]"/>
}
This is what shows up in the web browser:
Here is a screenshot of Intellisense:
So Picture is not null, it is a byte array. The image itself is a JPEG. Here is the code I am using to convert the image to a byte array to store it in the database:
[Authorize]
[HttpPost]
public ActionResult Create(Stock stock, HttpPostedFileBase file)
{
if (file != null)
{
if (file.ContentType.Contains("image"))
{
using (var inputStream = file.InputStream)
{
var memoryStream = inputStream as MemoryStream;
if (memoryStream == null)
{
memoryStream = new MemoryStream();
inputStream.CopyTo(memoryStream);
}
var data = memoryStream.ToArray();
stock.Picture = data;
}
}
}
if (ModelState.IsValid)
{
db.UserProfiles.Add(stock);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(stock);
}
I have checked the Database and the field is indeed populated. Here is my Stock model:
[Table("Stock")]
public class Stock
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int CarID { get; set; }
public byte[] Picture { get; set; }
//etc etc
}
I am tearing my hair out here trying to work out why this isn't working, as I think I have done everything right. What am I doing wrong?
Thanks very much
You're misunderstanding the <img> tag.
<img src="..." /> allows you to display an image from a URL.
The src attribute must specify a URL that returns the actual image.
If you want to embed the image in the page, you can use a data: URI.
Related
As you can see I want to add directly image file to the sql server by getting id, carId, uploadDate as Json and imagePath as file byte array.
How can I do that what should I change ?
The default model binder can not handle byte arrays that would be set to null.
As #viveknuna mentioned, if possible, you can try to use IFormFile to process or save the uploaded file.
Besides, if you really want to bind selected file to byte arrays, you can try to implement and use a custom model binder, like below.
public class ImageToByteArrayModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
// ...
// implement it based on your actual requirement
// code logic here
// ...
if (bindingContext.ActionContext.HttpContext.Request.Form.Files["ImagePath"]?.Length > 0)
{
var fileBytes = new byte[bindingContext.ActionContext.HttpContext.Request.Form.Files["ImagePath"].Length];
using (var ms = new MemoryStream())
{
bindingContext.ActionContext.HttpContext.Request.Form.Files["ImagePath"].CopyTo(ms);
fileBytes = ms.ToArray();
}
bindingContext.Result = ModelBindingResult.Success(fileBytes);
}
return Task.CompletedTask;
}
}
Apply the ModelBinder attribute to model property
[ModelBinder(BinderType = typeof(ImageToByteArrayModelBinder))]
public byte[] ImagePath { get; set; }
Test Result
This is to submit a view that uses ajax to pull the data.
I am trying to retrieve an image from MongoDb GridFS bucket. The download operation works. But the issue is, the view model that I use has:
public User User { get; set; }
public List<IFormFile> ImageUpload { get; set; }
I get the user from the db context, and use that to identify the image from the bucket and I want to return it to the view from the controller.
The following is my controller code:
public IActionResult AddEditUser(int id = 0)
{
if (id == 0)
{
return View(new UserImgBinder());
}
else
{
var userImageId = _context.User.Where(x => x.UserId.Equals(id)).Select(y => y.AvatarImg).ToString();
var stream = ContextNew.ImagesBucket.OpenDownloadStream(new ObjectId(userImageId.ToBson()));
var contentType = stream.FileInfo.Metadata["ContentType"].AsString;
//File(stream, contentType);
IFormFile file = new FormFile(stream, 0, stream.Length,"","");
var UserImgBinder = new UserImgBinder
{
User = _context.User.Where(x => x.UserId.Equals(id)).FirstOrDefault(),
ImageUpload = file
};
return View(UserImgBinder);
}
}
Since ImageUpload is of type List and what I am trying to feed it is not a list I am getting error.
What should I write to solve this? Is this approach bad?
Please help.
Thanks.
Try code like:
var UserImgBinder = new UserImgBinder
{
User = _context.User.Where(x => x.UserId.Equals(id)).FirstOrDefault(),
ImageUpload = new List<IFormFile> {
file
}
};
My requirement is to get the images from the database and display in front end.In my case i am using asp.net MVC . Database ir oracle and the data type of the image is blob .The follwing is my code
Model
This is the Model for the class and it has two properties ImageDisplay and ImageStream.
public class SelectionModel
{
public byte[] ImageDsiplay { get; set; }
public MemoryStream ImageStream { get; set;}
}
Controller Code
In the controller I'm trying the get the image from he database and assign to the Model.
public ActionResult Index()
{
SelectionModel sel = new SelectionModel();
List<SelectionModel> lissel = new List<SelectionModel>();
byte[] imagedata;
string sql = "select filecontent from filestore";
OracleConnection con = new OracleConnection(ConStr);
OracleCommand com = new OracleCommand(sql, con);
try
{
con.Open();
OracleDataReader dr;
dr = com.ExecuteReader();
while (dr.Read())
{
imagedata = (byte[])dr[0];
sel.ImageDsiplay = imagedata;
var stream = new MemoryStream(sel.ImageDsiplay);
sel.ImageStream = stream;
lissel.Add(sel);
}
}
catch (Exception ex)
{
// ??
}
//Here i am trying to return the list .
return View(lissel);
}
View Code
The Following is the view code and it should display the image .
#model IEnumerable<GoldForGold.Models.SelectionModel>
<table>
<tr>
<td>
#foreach (var item in Model)
{
<img src="#Url.Action("Index", "Selection")" alt="myimage" />
}
</td>
</tr>
</table>
ISSUE
The issue is i am not able to display the images from the database. Image is not displayed.I have tried for quite sometime but not able to figure out the issue
Historically, I've used an IHttpHandler for this sort of thing. Something like this:
public class EmployeePhotoHandler : IHttpHandler
{
public bool IsReusable { get { return false; } }
public void ProcessRequest(HttpContext context)
{
int employeeID;
if (!int.TryParse(context.Request.QueryString["ID"], out employeeID))
return;
EmployeePhoto photo = EmployeeService.GetPhotoByEmployee(EmployeeService.GetEmployeeByID(employeeID));
if (photo == null || photo.Photo == null)
return;
context.Response.ContentType = "image/jpeg";
context.Response.BinaryWrite(photo.Photo);
}
}
I use the WebImage class in my controllers for dynamically rendering and resizing image in the DB:
[ImageOutputCache(Duration = 18000)]
public void Image(int id)
{
Image image = ImageDAL.SelectSingle(e => e.ImageId == id); //EF Model
WebImage webimage = new WebImage(image.Data); //image.Data (byte[])
//resize, crop etc
webimage.Write();
}
Here is the attribute code for the output caching (otherwise the cache outputs a content type of text/html):
public class ImageOutputCache : OutputCacheAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
base.OnResultExecuting(filterContext);
filterContext.HttpContext.Response.ContentType = "image/jpeg";
}
}
hi i am doing a project in MVC4 using c#.
in my project i am storing some group of persons details in database with unique id.and also storing the profile pic of particular person in a folder in my project.(Id number and pic name is same).
in view i want display all these details.Problem is in images. I use the following codes
View
#foreach(var item in Model)
{
<td><img src="#Url.Action("ImageRetrive", "Member", new {imgname=(item.Id)})" /><br />Rtn. #item.Mem_NA<br />(#item.Mem_Occ)</td>
}
controller
public string ImageRetrive(int imgname)
{
string keyword=image.ToString();
string imagefolderpath = Server.MapPath("~/Content/Member/MemberPhotos");
string currentimage = new Member().GetImage(imagefolderpath,keyword);
string fullpath = "~/Content/Member/MemberPhotos/" + currentimage;
return fullpath;
}
model
public string GetImage(string path,string keyword)
{
DirectoryInfo di = new DirectoryInfo(path);
FileInfo[] images = di.GetFiles();
foreach (FileInfo image in images)
{
var name = image.Name;
if (name.Contains(keyword))
{
imgname = name;
}
}
return imgname;
}
But i didnot get any output. in the controller the variable fullpath is giving the link. but it can take in . Please help me.
I think you need is FilePathResult, change your controller code as
public FilePathResult ImageRetrive(int imgname)
{
string keyword=image.ToString();
string imagefolderpath = Server.MapPath("~/Content/Member/MemberPhotos");
string currentimage = new Member().GetImage(imagefolderpath,keyword);
string fullpath = "~/Content/Member/MemberPhotos/" + currentimage;
return File(fullpath, "image/png"); //Changed here
}
or You can use FileContentResult
public FileContentResult Retrive(int imgname)
{
return File(ConvertToByteArray(YourFile), "image/png"); //Changed here
}
In your view you pass imgname as parameter and in your controller you get image.
Controller
public string ImageRetrive(int imgname){ }
Change return path
return File(fullpath, "text/plain");
here's my question: I have an MVC3 C# application and I need to update a value in a DbSet from the Edit controller, so the T item's value will be replaced with a new one. I don't want to delete the item and add it again. I cannot figure out how to do this. DbSet doesn't seem to have something like an index.
Here's my Edit controller:
public class ItemController : Controller
{
private SESOContext db = new SESOContext();
private FindQrs fqr = new FindQrs();
[HttpPost]
public ActionResult Edit(Item item)
{
if (ModelState.IsValid)
{
db.Entry(item).State = EntityState.Modified;
Qr qr = fqr.FindQr(item.QR);
// update somewhere here
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.SetID = new SelectList(db.Sets, "SetID", "Name", item.SetID);
return View(item);
}
}
EDIT: The above controller is for the Item entity which on Create action creates instances of the Qr entity. I just want to add something which on Edit action will update the Value field of the Qr entity with the value from the view (the Value field of Qr is supposed to be unique).
Where FindQrs method looks like this:
public class FindQrs
{
private SESOContext db = new SESOContext();
public Qr FindQr(string qr)
{
List<Qr> qrList = db.Qrs.ToList<Qr>();
Qr foundQr = qrList.Find(delegate(Qr qrDel) { return qrDel.Value == qr; });
return foundQr;
}
}
And Qr is a class which contains only an ID and a string Value fields.
Qrs is the mentioned DbSet from the context. It looks like this:
public DbSet<Qr> Qrs { get; set; }
Any help will be appreciated.
You are perhaps updating the value in a different DbContext. Try this:
[HttpPost]
public ActionResult Edit(Item item)
{
if (ModelState.IsValid)
{
db.Entry(item).State = EntityState.Modified;
Qr qr = fqr.FindQr(item.QR, db);
// update somewhere here
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.SetID = new SelectList(db.Sets, "SetID", "Name", item.SetID);
return View(item);
}
public class FindQrs
{
public Qr FindQr(string qr, SESOContext db) // pass in the db context
{
List<Qr> qrList = db.Qrs.ToList<Qr>();
Qr foundQr = qrList.Find(delegate(Qr qrDel) { return qrDel.Value == qr; });
return foundQr;
}
}