I'm attempting to add an image to a table and link it to a product. Here's the database table setup.
---- TWebProducts ----
intWebProductID
... A bunch of other variables that don't matter here
---- TWebProductImages ----
intWebProductID
intWebImageID
---- TWebImages ----
intWebImageID
varImage
Here's what I'm attempting to do which, is not working.
[HttpPost]
public ActionResult ProductEdit(IEnumerable<HttpPostedFileBase> files, TWebProduct tbl, HttpPostedFileBase file)
{
// Thumbnail image
if (file != null)
{
string path = null;
string pic = null;
pic = System.IO.Path.GetFileName(file.FileName);
path = System.IO.Path.Combine(Server.MapPath("~/ProductThumbnails/"), pic);
// file is uploaded
file.SaveAs(path);
tbl.varThumbnailImage = pic;
}
tbl.dteModified = DateTime.Now;
tbl.intCompanyID = 1;
// update the images
string fName = "";
try
{
//loop through all the files
foreach (var img in files)
{
//Save file content goes here
fName = img.FileName;
if (img != null && img.ContentLength > 0)
{
#region ImageSaving Stuff
var originalDirectory = new DirectoryInfo(string.Format("{0}ProductImages\\", Server.MapPath(#"\")));
//string pathString = System.IO.Path.Combine(originalDirectory.ToString(), "imagepath");
string pathString = originalDirectory.ToString();
var fileName1 = Path.GetFileName(img.FileName);
bool isExists = System.IO.Directory.Exists(pathString);
if (!isExists)
System.IO.Directory.CreateDirectory(pathString);
var path = string.Format("{0}\\{1}", pathString, img.FileName);
img.SaveAs(path);
#endregion
// this is the important part
// Get all the data saved to a variable
TWebImage webImage = new TWebImage();
webImage.varImage = path;
// Add to the TWebImages and link to the Product
tbl.TWebImages.Add(webImage);
}
}
// Update the product
_unitOfWork.GetRepositoryInstance<TWebProduct>().Update(tbl);
}
catch (Exception ex)
{
}
return RedirectToAction("Products");
}
There's no error, but there's nothing in the link table or the images table.
Obviously I'm doing something wrong. I'm new to using ADO Entity and repositories. I'm pretty well versed in SQL and C#.
I don't know what to google or even what to look for. Any and all help is appreciated. Let me know if I can clarify anything.
Related
I have an ASP.NET MVC project that is working fine to save images to different folders and sub folders. But when I want to do similarly in ASP.NET Core 2.2, it is not working as it is and I need help to solve this problem and I would appreciate your help very much.
Here is my ASP.NET MVC version that not working in ASP.NET Core 2.2:
public ActionResult AddCar(CarVM model, HttpPostedFileBase file)
{
using (ApplicationDbContext db = new ApplicationDbContext())
{
Car c = new Car();
c.Name = model.Name;
c.Mileage = model.MileAge;
db.Car.Add(c);
db.SaveChanges();
// Get Inserted Id;
int id = c.CarId;
}
// to insert Image of the car in different folders in ASP.NET MVC I do like this, but this not working in ASP.NET Core 2.2
// Create necessary directories
var originalDirectory = new DirectoryInfo(string.Format("{0}Images\\Uploads", Server.MapPath(#"\")));
// I add folder "CarsImage" because I have other Products image too
var pathString1 = Path.Combine(originalDirectory.ToString(), "CarsImage");
var pathString2 = Path.Combine(originalDirectory.ToString(), "CarsImage\\" + id.ToString());
var pathString3 = Path.Combine(originalDirectory.ToString(), "CarsImage\\" + id.ToString() + "\\Thumbs");
var pathString4 = Path.Combine(originalDirectory.ToString(), "CarsImage\\" + id.ToString() + "\\Gallery");
var pathString5 = Path.Combine(originalDirectory.ToString(), "CarsImage\\" + id.ToString() + "\\Gallery\\Thumbs");
// Check if directory exist, if not then create them
if (!Directory.Exists(pathString1))
Directory.CreateDirectory(pathString1);
if (!Directory.Exists(pathString2))
Directory.CreateDirectory(pathString2);
if (!Directory.Exists(pathString3))
Directory.CreateDirectory(pathString3);
if (!Directory.Exists(pathString4))
Directory.CreateDirectory(pathString4);
if (!Directory.Exists(pathString5))
Directory.CreateDirectory(pathString5);
// Check if file was uploaded
if (file != null && file.ContentLength > 0)
{
// Get file extension
string ext = file.ContentType.ToLower();
// Verify extension
if (ext != "image/jpg" &&
ext != "image/jpeg" &&
ext != "image/pjpeg" &&
ext != "image/gif" &&
ext != "image/x-png" &&
ext != "image/png")
{
using (ApplicationDbContext db = new ApplicationDbContext())
{
model.Categories = new SelectList(db.Category.ToList(), "CategoryId", "CategoryName");
model.Mileages = new SelectList(db.MileAge.ToList(), "MileAgeId", "Mile");
ModelState.AddModelError("", "The image was not uploaded - Wrong image extension");
return View(model);
}
}
// Init image name
string imageName = file.FileName;
// Save image name to Car table
using (ApplicationDbContext db = new ApplicationDbContext())
{
Car dto = db.Car.Find(id);
dto.ImageName = imageName;
db.SaveChanges();
}
// Set Original and image paths
var path = string.Format("{0}\\{1}", pathString2, imageName);
var path2 = string.Format("{0}\\{1}", pathString3, imageName);
// Save Original
file.SaveAs(path); // Not working in core
// Create and save thumb
WebImage img = new WebImage(file.InputStream); // WebImage not working in core
img.Resize(200, 200);
img.Save(path2);
}
}
So I have tried with IFormFile.... and
string uploadFolder = Path.Combine(hostingEnvirnment.WebRootPath, "images\\upload");
But I don't how to do. Please help!
In ASP.NET Core , you could use Directory.GetCurrentDirectory() to get the current working directory of the application and combine the folder path under the static file root directory .
var originalDirectory = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot\\Images\\Uploads");
Then use Path.Combine() to set the original and image paths , and you could save the files of type IFormFile like below :
// Set Original and image paths
var filePath = Path.Combine(pathString2, imageName);
var filePath2 = Path.Combine(pathString3, imageName);
// Save Original
file.CopyTo(new FileStream(filePath, FileMode.Create));
For saving the thumbnail image , you could Installed System.Drawing.Common package and use the below code :
Stream stream = file.OpenReadStream();
Image newImage = GetReducedImage(200, 200, stream);
newImage.Save(filePath2);
public Image GetReducedImage(int width, int height, Stream resourceImage)
{
try
{
Image image = Image.FromStream(resourceImage);
Image thumb = image.GetThumbnailImage(width, height, () => false, IntPtr.Zero);
return thumb;
}
catch (Exception e)
{
return null;
}
}
The complete code is as follows:
public readonly ApplicationDbContext _context;
public HomeController( ApplicationDbContext context)
{
_context = context;
}
[HttpPost]
public ActionResult AddCar(Car model, IFormFile file)
{
Car c = new Car();
c.Name = model.Name;
c.Mileage = model.MileAge;
_context.Car.Add(c);
_context.SaveChanges();
// Get Inserted Id;
int id = c.CarId;
// Create necessary directories
var originalDirectory = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot\\Images\\Uploads");
// different image folder
var pathString1 = Path.Combine(originalDirectory.ToString(), "CarsImage");
var pathString2 = Path.Combine(originalDirectory.ToString(), "CarsImage\\" + id.ToString());
var pathString3 = Path.Combine(originalDirectory.ToString(), "CarsImage\\" + id.ToString() + "\\Thumbs");
var pathString4 = Path.Combine(originalDirectory.ToString(), "CarsImage\\" + id.ToString() + "\\Gallery");
// Check if directory exist, if not then create them
if (!Directory.Exists(pathString1))
Directory.CreateDirectory(pathString1);
if (!Directory.Exists(pathString2))
Directory.CreateDirectory(pathString2);
if (!Directory.Exists(pathString3))
Directory.CreateDirectory(pathString3);
if (!Directory.Exists(pathString4))
Directory.CreateDirectory(pathString4);
// Check if file was uploaded
if (file != null && file.Length > 0)
{
// Get file extension
string ext = file.ContentType.ToLower();
// Verify extension
if (ext != "image/jpg" &&
ext != "image/jpeg" &&
ext != "image/pjpeg" &&
ext != "image/gif" &&
ext != "image/x-png" &&
ext != "image/png")
{
using (ApplicationDbContext db = new ApplicationDbContext())
{
model.Categories = new SelectList(db.Category.ToList(), "CategoryId", "CategoryName");
model.Mileages = new SelectList(db.MileAge.ToList(), "MileAgeId", "Mile");
ModelState.AddModelError("", "The image was not uploaded - Wrong image extension");
return View();
}
}
// Init image name
string imageName = file.FileName;
// Save image name to Car table
Car dto = _context.Car.Find(id);
dto.ImageName = imageName;
_context.SaveChanges();
// Set Original and image paths
var filePath = Path.Combine(pathString2, imageName);
var filePath2 = Path.Combine(pathString3, imageName);
// Save Original
file.CopyTo(new FileStream(filePath, FileMode.Create));
// Create and save thumb
Stream stream = file.OpenReadStream();
Image newImage = GetReducedImage(200, 200, stream);
newImage.Save(filePath2);
}
return View();
}
public Image GetReducedImage(int width, int height, Stream resourceImage)
{
try
{
Image image = Image.FromStream(resourceImage);
Image thumb = image.GetThumbnailImage(width, height, () => false, IntPtr.Zero);
return thumb;
}
catch (Exception e)
{
return null;
}
}
You need to use IHostingEnvironment to get the application path in ASP.NET Core. Check this SO answer for more details.
I want to upload the excel file of record 2500. This process takes time more than 5 minutes approximate. I want to optimize it to less than a minute maximum.
Find the best way of optimization of that code. I am using Dbgeography for location storing. File is uploaded and save the data properly. Everything is working find but I need optimization.
public ActionResult Upload(HttpPostedFileBase FileUpload)
{
if (FileUpload.ContentLength > 0)
{
string fileName = Path.GetFileName(FileUpload.FileName);
string ext = fileName.Substring(fileName.LastIndexOf('.'));
Random r = new Random();
int ran = r.Next(1, 13);
string path = Path.Combine(Server.MapPath("~/App_Data/uploads"), DateTime.Now.Ticks + "_" + ran + ext);
try
{
FileUpload.SaveAs(path);
ProcessCSV(path);
ViewData["Feedback"] = "Upload Complete";
}
catch (Exception ex)
{
ViewData["Feedback"] = ex.Message;
}
}
return View("Upload", ViewData["Feedback"]);
}
Here is other method from where the file is uploaded and save it to the database..
private void ProcessCSV(string filename)
{
Regex r = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");
StreamReader sr = new StreamReader(filename);
string line = null;
string[] strArray;
int iteration = 0;
while ((line = sr.ReadLine()) != null)
{
if (iteration == 0)
{
iteration++;
continue; //Because Its Heading
}
strArray = r.Split(line);
StoreLocation store = new StoreLocation();
store.Name = strArray[0];
store.StoreName = strArray[1];
store.Street = strArray[2];
store.Street2 = strArray[3];
store.St_City = strArray[4];
store.St_St = strArray[5];
store.St_Zip = strArray[6];
store.St_Phone = strArray[7];
store.Office_Phone = strArray[8];
store.Fax = strArray[9];
store.Ownership = strArray[10];
store.website = strArray[11];
store.Retailer = check(strArray[12]);
store.WarehouseDistributor = check(strArray[13]);
store.OnlineRetailer = check(strArray[14]);
string temp_Add = store.Street + "," + store.St_City;
try
{
var point = new GoogleLocationService().GetLatLongFromAddress(temp_Add);
string points = string.Format("POINT({0} {1})", point.Latitude, point.Longitude);
store.Location = DbGeography.FromText(points);//lat_long
}
catch (Exception e)
{
continue;
}
db.StoreLocations.Add(store);
db.SaveChanges();
}
The obvious place to start would be your external call to the Geo Location service, which it looks like you are doing for each iteration of the loop. I don't know that service, but is there any way you can build up a list of addresses in memory, and then hit it once with multiple addresses, then go back and amend all the records you need to update?
The call to db.SaveChanges() which updates the database, this is happening for every line.
while (...)
{
...
db.StoreLocations.Add(store);
db.SaveChanges(); // Many database updates
}
Instead, just call it once at the end:
while (...)
{
...
db.StoreLocations.Add(store);
}
db.SaveChanges(); // One combined database update
This should speed up your code nicely.
Here I add product and save path of image, everything works fine and image path is saved
public ActionResult AddProduct(Product p, HttpPostedFileBase prodImg, decimal[] price)
{
try
{
string absoluthFolderPath = Server.MapPath("\\Images");
string pathOfImage = System.IO.Path.GetExtension(prodImg.FileName);
string newFileName = Guid.NewGuid() + pathOfImage;
absoluthFolderPath += "\\" + newFileName;
prodImg.SaveAs(absoluthFolderPath);
string relitivePath = #"\Images\" + newFileName;
p.ImagePath = relitivePath;
p.Blocked = false;
new ProductsBL().AddProduct(p);
ViewData\["msg"\] = "Successfuly";
}
catch(Exception ex)
{
}
ModelState.Clear();
return View();
}
When trying to update image path it gives me error shown on screenshot
public ActionResult Update(Product modifieDetails, HttpPostedFileBase updImg)
{
string absoluthFolderPath = Server.MapPath("\\Images");
string pathOfImage = System.IO.Path.GetExtension(updImg.FileName);
string newFileName = Guid.NewGuid() + pathOfImage;
absoluthFolderPath += "\\" + newFileName;
updImg.SaveAs(absoluthFolderPath);
string relitivePath = #"\Images\" + newFileName;
modifieDetails.ImagePath = relitivePath;
modifieDetails.Blocked = false;
new ProductsBL().UpdateProduct(modifieDetails);
return RedirectToAction("ListProduct");
}
[1]: http://i.stack.imgur.com/wgE88.png
You need to split this up:
new ProductsBL().AddProduct(p);
In order to save updates to an entity back to the store, you have to set "IsModified" on the entity, and then save the context. Like so...
using (ProductsBL context = new ProductsBL()) {
var p = (some query to get it from the store);
p.ImagePath = relitivePath;
p.Blocked = false;
p.IsModified = true;
context.SaveChanges();
}
As it is, you're creating a new entity and adding that to the store, not updating the existing one.
And, if you're coding in English, please fix the spellings: Modify, Relative, absolute.
I have a kendo ui async file upload with the following options on my view.
<div class="demo-section">
#(Html.Kendo().Upload()
.Name("files")
.Async(a => a
.Save("Save", "Upload")
.AutoUpload(true)
)
)
</div>
In the corresponding action method ,I would like to set my model's properties for filename .Shown below is what i have currently .
public ActionResult Save(IEnumerable<HttpPostedFileBase> files)
{
// The Name of the Upload component is "files"
if (files != null)
{
foreach (var file in files)
{
// Some browsers send file names with full path.
// We are only interested in the file name.
var fileName = Path.GetFileName(file.FileName);
var physicalPath = Path.Combine(Server.MapPath("~/App_Data"), fileName);
// The files are not actually saved in this demo
// file.SaveAs(physicalPath);
}
}
// Return an empty string to signify success
return Content("");
}
If there is a way to do it ,please let me know ..
public ActionResult Save(IEnumerable<HttpPostedFileBase> files)
{
var savedFilePaths = new List<string>();
var applicationPath = System.Web.HttpContext.Current.Request.Url.Scheme + "://" + System.Web.HttpContext.Current.Request.Url.Authority + System.Web.HttpContext.Current.Request.ApplicationPath + "/Content/Images/Others/";
// The Name of the Upload component is "files"
if (files != null)
{
foreach (var file in files)
{
// Some browsers send file names with full path.
// We are only interested in the file name.
var fileName = Path.GetFileName(file.FileName);
if (fileName != null)
{
fileName = DateTime.Now.ToString("yyyyMMddmm-") + fileName;
var physicalPath = Path.Combine(Server.MapPath("~/Upload/Hotel"), fileName);
file.SaveAs(physicalPath);
savedFilePaths.Add(applicationPath + fileName);
}
}
}
// Return an empty string to signify success
return Content("");
}
I Make Upload Image In Asp.Net And I Really Save The Image In The Data Base But When i Want To Make A Query To Select The Image It Return The Source Of The Image With No Image Please I Want Any One Know The Solution Please Help Me.`enter code here This Is The Controller Code:
public ActionResult UpLoadImage(HttpPostedFileBase file)
{
if (file != null)
{
UpLoadDBEntities context = new UpLoadDBEntities();
file = Request.Files[0];
string filename = file.FileName;
string contenttype = file.ContentType;
string full = filename + " " + contenttype;
//string path = System.IO.Path.Combine(
// Server.MapPath("~/images/") + file.FileName);
file.SaveAs(HttpContext.Server.MapPath("~/Images/")
+ file.FileName);
Image_table it = new Image_table();
it.Image_Path = filename;
context.Image_table.Add(it);
context.SaveChanges();
}
return View();
}
public JsonResult ShowImage()
{
UpLoadDBEntities context = new UpLoadDBEntities();
Image_table it = new Image_table();
var showimage = (from itbl in context.Image_table
where itbl.ID == 8
select new { itbl.Image_Path });
return Json(showimage , JsonRequestBehavior.AllowGet);
}
You are setting the path as
it.Image_Path = filename;
Yet it gets store on the server as
file.SaveAs(HttpContext.Server.MapPath("~/Images/")
+ file.FileName);
I hope you can see it needs to be it.Image_Path = "~/Images/" + filename;. Also, make sure folks can actually access the path through IIS.