I work on ASP.NET Core 2.2 Web API and face an issue: I can't use replace function to change the name property of a selected file that I get when uploaded.
When I try like this:
string fileName = DisplayFileName.Replace(".xlsx", "-") + Guid.NewGuid().ToString() + ".xlsx";
I get an error
Iform file doesn't contain definition for replace and no accessible extension method Replace accepting first argument of iformfile
Full sample is here:
[HttpPost, DisableRequestSizeLimit]
public IActionResult Upload()
{
try
{
var DisplayFileName = Request.Form.Files[0];
string fileName = DisplayFileName.Replace(".xlsx", "-") + Guid.NewGuid().ToString() + ".xlsx";
string Month = DateTime.Now.Month.ToString();
string DirectoryCreate = myValue1 + Month;
Path.Combine(Directory.GetCurrentDirectory(), folderName);
if (!Directory.Exists(DirectoryCreate))
{
Directory.CreateDirectory(DirectoryCreate);
}
if (DisplayFileName.Length > 0)
{
var filedata = ContentDispositionHeaderValue.Parse(Request.Form.Files[0].ContentDisposition).FileName.Trim('"');
var dbPath = Path.Combine(DirectoryCreate, fileName);
using (var stream = new FileStream(dbPath, FileMode.Create))
{
Request.Form.Files[0].CopyTo(stream);
}
return Ok(new { dbPath });
}
else
{
return BadRequest();
}
}
catch (Exception ex)
{
return StatusCode(500, $"Internal server error: {ex}");
}
}
How to solve this issue?
sample
suppose i select file developed.xlsx
then after use replace or any way result will be
developed-sddfn78888.xlsx
You can use System.IO.Path to get filename and get file extension from request files.
Change this
string fileName = DisplayFileName.Replace(".xlsx", "-") + Guid.NewGuid().ToString() + ".xlsx";
To
string filename = Path.GetFileName(DisplayFileName.FileName);
string fileExtension = Path.GetExtension(DisplayFileName.FileName);
string newFileName = $"{filename}-{Guid.NewGuid().ToString()}{fileExtension}";
Otherwise, you could modify your code to
string fileName = DisplayFileName.FileName.Replace(".xlsx", "-") + Guid.NewGuid().ToString() + ".xlsx";
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 save my image File using session ID value and then in the uploads folder I want to pass the ID value like 3.jpeg or png
[HttpPost]
public ActionResult AddImage(HttpPostedFileBase postedFile)
{
int compId = Convert.ToInt32(Session["compID"]);
if (postedFile != null)
{
string path = Server.MapPath("~/Uploads/");
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
postedFile.SaveAs(path + Path.GetFileName(postedFile.FileName));
ViewBag.Message = "File uploaded successfully.";
}
return RedirectToAction("AddCompany");
}
Below i have attached the image
When saving your image, you need to combine the compId and the file extension as follows:
var filename = compId.ToString() + Path.GetExtension(postedFile.FileName);
So your code should look something like this:
[HttpPost]
public ActionResult AddImage(HttpPostedFileBase postedFile)
{
int compId = Convert.ToInt32(Session["compID"]);
if (postedFile != null)
{
string path = Server.MapPath("~/Uploads/");
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
var filename = compId.ToString() + Path.GetExtension(postedFile.FileName);
postedFile.SaveAs(path + filename);
ViewBag.Message = "File uploaded successfully.";
}
return RedirectToAction("AddCompany");
}
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.
ok I have this code that handle a file been upload through a simple web form
CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(#"C:\inetpub\wwwroot\myapp\Images");
//var provider = new MultipartFormDataStreamProvider(#"C:\inetpub\wwwroot\myapp\Images");
var Image = "";
var Dir = "";
var CurrentPath = "";
string UploadType = "";
string ImageName = "";
// Read the form data.
await Request.Content.ReadAsMultipartAsync(provider);
// Show all the key-value pairs.
foreach (var key in provider.FormData.AllKeys)
{
foreach (var val in provider.FormData.GetValues(key))
{
if (key == "uploadType") UploadType = val;
if (key == "imageName") ImageName = val;
//Trace.WriteLine(string.Format("{0}: {1}", key, val));
}
}
foreach (MultipartFileData file in provider.FileData)
{
//Debug.WriteLine(file.Headers.ContentDisposition.FileName);
//Debug.WriteLine("Server file path: " + file.LocalFileName);
Image = Path.GetFileName(file.LocalFileName);
Dir = Path.GetDirectoryName(file.LocalFileName);
CurrentPath = file.LocalFileName;
}
if (UploadType == "update")
{
File.Delete(Dir + "\\" + Image);
File.Move(CurrentPath, Dir + "\\" + Image);
Imagen = ImageName;
}
return Request.CreateResponse(HttpStatusCode.OK, Image);
as some docs mention using await will cause the read process to be async, my problem is that I need to know when the file has been saved into the folder cause I want to delete it after if the UploadType form field is == to update, but it seems like when try this line
File.Delete(Dir + "\\" + Image);
the image is has not been saved yet and I got an error that the image don't exist, so my question is, how I can tell or be sure the image is ready in the dir? how can I tell the async process ends, thanks for any help on this!!
File.Exists is the method you should use.
Aside You should be using Path.Combine instead of building the path with concatenation.