Saving And fetching images MongoDB - c#

i have created method that create a User which in following i want it to create user Profile with it.
here is my code:
public Task CreateUser(User user, IFormFile image)
{
if (image is not null && image.Length > 0)
{
string uploads = Path.Combine(#"./", "Uploads");
Directory.CreateDirectory(uploads);
if (image.Length > 0)
{
var filename = Guid.NewGuid().ToString() + image.FileName;
string filePath = Path.Combine(uploads, filename);
using (Stream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
image.CopyTo(fileStream);
}
user.Image = filename;
}
}
else
{
user.Image = "";
}
return _user.InsertOneAsync(user);
}
but then when i want to create user in UI
#inject IUserData Userdata
await Userdata.CreateUser(user);
i got an error under createuser and it says i should pass the image parameter which when i pass it again gives me another error
can you please help me with saving this image?
thanks

Related

How to check if the filename already exists

I need little help to modify my function. How can I check if the file already exists with the same name? and if it does then to add a newguid string to the name and save the new file.
public string UploadStorageFile(StorageModel newFile, int userId)
{
string uniqueFileName = null;
if(newFile.FileName != null)
{
string uploadsFolder = Path.Combine(_webHostEnvironment.WebRootPath, $"repositories/{userId}");
if (!Directory.Exists(uploadsFolder))
{
Directory.CreateDirectory(uploadsFolder);
}
uniqueFileName = Guid.NewGuid().ToString() + "_" + newFile.FileName.FileName;
string filePath = Path.Combine(uploadsFolder, uniqueFileName);
using(var fileStream = new FileStream(filePath, FileMode.Create))
{
newFile.FileName.CopyTo(fileStream);
}
}
return uniqueFileName;
}
For Checking, if a File already exists, you can use the File.Exists() method.
Here is a basic example, on how to check if a File does already exist:
public bool DoesFileAlreadyExist(string uploadFolder, string fileName)
{
var file = $"{uploadFolder}\{fileName}";
return File.Exists(file);
}
Specific on your Code, you could use the method like in this example (Just call the method, and check if it is existing):
public string UploadStorageFile(StorageModel newFile, int userId)
{
string uniqueFileName = null;
if(newFile.FileName != null)
{
string uploadsFolder = Path.Combine(_webHostEnvironment.WebRootPath, $"repositories/{userId}");
if (!Directory.Exists(uploadsFolder))
{
Directory.CreateDirectory(uploadsFolder);
}
if (!DoesFileAlreadyExist(uploadsFolder, newFile.Filename)
{
uniqueFileName = Guid.NewGuid().ToString() + "_" + newFile.FileName.FileName;
string filePath = Path.Combine(uploadsFolder, uniqueFileName);
using(var fileStream = new FileStream(filePath, FileMode.Create))
{
newFile.FileName.CopyTo(fileStream);
}
}
return uniqueFileName;
}
return "NO FILE CREATED";
}

Cannot upload file from form .NET

I'm trying to upload data (image) from form to my .NET App. It saves the Path to the database correctly, but the images are not saved under "wwwroot/images". I will be grateful for your help.
public async Task<IActionResult> Create([Bind("Id,Brand,Model,Description,Price,ImageUrl,CategoryId")] Car car)
{
if (ModelState.IsValid)
{
string webRootPath = _hostEnvironment.WebRootPath;
var files = HttpContext.Request.Form.Files;
if (files.Count > 0)
{
string fileName = Guid.NewGuid().ToString();
var uploads = Path.Combine(webRootPath, "images");
var extenstion = Path.GetExtension(files[0].FileName);
var filePath = Path.Combine(uploads, fileName, extenstion);
car.ImageUrl = "images" + "\\" + fileName + extenstion;
using (var filesStreams = new FileStream(filePath, FileMode.Create))
{
files[0].CopyTo(filesStreams);
}
}
_context.Add(car);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["CategoryId"] = new SelectList(_context.Categories, "Id", "Name", car.CategoryId);
return View(car);
}

System.UnauthorizedAccessException: Access to the path '...' is denied

So, I'm kinda new to .NET core and I'm having a problem to copy a IFormFile to a folder in my project. I've been trying to see other questions about it but none of the answers had helped me. That's my code:
public async Task<string> AddImage(IFormFile image, int id)
{
if (image.Length > 0)
{
var filePath = Path.Combine("images", ("apartamento" + id.ToString()), image.FileName);
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
await image.CopyToAsync(fileStream);
}
return filePath;
}
}
The problem is that it seems that I don't have permission (tried hard to see if everything is authorized) or something about my code it's not right.
I just wanna do a simple thing: receive an image in my API and save it so I can use in my project later. I have done it before but I'm facing some issues with .NET core.
If someone have other idea to do it, I'll be thankful. I'm thinking about saving the image as Base64 in my database but I'm not sure about which is the best option. Or the easiest.
Try this
public async Task<string> AddImage(IFormFile image, int id)
{
if (image.Length > 0)
{
var dir = Path.Combine("images", ("apartamento" + id.ToString()));
var filePath = Path.Combine(dir, image.FileName);
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
await image.CopyToAsync(fileStream);
}
return filePath;
}
}

How to display image angular from .net core API and database

I would like to display a picture whose path it stores in the database
this is how it transfers the image file to the database.
public string UploadImage(IFormFile file)
{
if (file == null) throw new Exception("Pusty plik");
if (file.Length == 0)
{
throw new Exception("Pusty plik");
}
if (!ACCEPTED_FILE_TYPES.Any(s => s == Path.GetExtension(file.FileName).ToLower())) throw new Exception("Zły typ pliku");
if (string.IsNullOrWhiteSpace(host.WebRootPath))
{
host.WebRootPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");
}
var uploadFilesPath = Path.Combine(host.WebRootPath, "images");
if (!Directory.Exists(uploadFilesPath))
Directory.CreateDirectory(uploadFilesPath);
var fileName = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);
var filePath = Path.Combine(uploadFilesPath, fileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
file.CopyToAsync(stream);
}
var path = Path.Combine(Directory.GetCurrentDirectory(), #"/wwwroot/images/", fileName);
return path;
}
here stores files:
https://zapodaj.net/a8829a7a3a90b.png.html
In your sample code I do not see path returning from database.
Also from security point of view it would be bad practice to return /wwwroot/images/ in response. You can create a folder on shared location and return shared location path.
Seems you question and same code isn't aligning.

How to save Images to different folders in database using ASP.NET Core?

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.

Categories