System.UnauthorizedAccessException: Access to the path '...' is denied - c#

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;
}
}

Related

Uploading image via ASP.NET Core Web API gets corrupted

I'm developing an ASP.NET Core Web API that posts an image and saves it to the server.
When I using Visual Studio, it works fine and saves the image in the Pics directory.
But when uploading it to Windows VPS, it saves the file, but there is no size - it means it's corrupted.
[HttpPost]
public async Task<ActionResult<ImageFile>> PostImage([FromForm] ImageFile image)
{
try
{
// string Pic = Path.GetFileNameWithoutExtension(image.AttImage.FileName);
string path = Path.Combine(wwrootPath + "/Pics/" + RandomString(32) + ".jpg");
// Logger.LogError("Omar1 : " + path);
if (image.AttImage == null)
return null;
using (var filestream = new FileStream(path, FileMode.Create))
{
_= image.AttImage.CopyToAsync(filestream);
}
image.ImagePath = path;
image.CreatedDate = DateTime.UtcNow;
// Logger.LogError("Omar2 : "+path);
_context.Images.Add(image);
await _context.SaveChangesAsync();
return image;
}
catch (Exception ex)
{
Logger.LogError(ex.Message+" : "+ex.InnerException);
return null;
}
}
I searched for many solutions and give the Pics directory full control permission but the problem persists.
Does anyone have any idea?

.NET 7 System.IO.FileNotFoundException: Could not find file

This is my first time asking around here, so sorry if it's not worded very well.
I have a blazor WebAssembly project with MudBlazor, and when I try to upload files to save them into a database, it appears the next error message in the browser console.
System.IO.FileNotFoundException: Could not find file
When the user uploads the files I call the next method to save the files into IList<IBrowserFile>.
IList<IBrowserFile> Files = new List<IBrowserFile>();
private void OnInputFileChanged(InputFileChangeEventArgs e)
{
var files = e.GetMultipleFiles();
foreach(var file in files)
{
Files.Add(file);
}
}
Once the user has uploaded all the files, they click on a button that call the next method to upload it into a database.
[Inject] protected ISnackbar Snackbar { get; set; } = default!;
private async void Upload()
{
List<string>? notUploadFiles = null;
foreach(var file in Files)
{
byte[] fileBytes = File.ReadAllBytes(destPath + file.Name);
string extn = new FileInfo(file.Name).Extension;
var addArchivoTarea = new AddArchivoTareaRequestDTO(Tarea.Id, fileBytes, extn);
var successResponse = await HttpTareas.AddArchivoToTareaAsync(addArchivoTarea);
if (!successResponse)
{
notUploadFiles.Add(file.Name);
}
}
if(notUploadFiles is not null) {
Snackbar.Configuration.SnackbarVariant = Variant.Filled;
Snackbar.Add("The following files could not be uploaded:", Severity.Info);
Snackbar.Configuration.SnackbarVariant = Variant.Outlined;
foreach (var file in notUploadFiles)
{
Snackbar.Add(file, Severity.Error);
}
//Snackbar.Configuration.PositionClass = Defaults.Classes.Position.TopCenter;
//Snackbar.Add("TODO: Upload your files!", Severity.Normal);
MudDialog.Close(DialogResult.Ok(true));
}
Snackbar.Add("All files have been successfully uploaded", Severity.Success);
MudDialog.Close(DialogResult.Ok(true));
}
I don't know where is the problem, any idea?
The uploaded files are not in the file system, they are in-memory only. The way to access the raw data would be something like:
byte[] fileBytes;
using (Stream s = file.OpenReadStream())
{
MemoryStream ms = new MemoryStream();
await s.CopyToAsync(ms);
fileBytes= ms.ToArray();
}

Saving And fetching images MongoDB

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

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.

C# Saving an MP4 Resource to a file

I've tried a few different ways but it won't open when it's saved. How can I accomplish this?
Basically I want to be able to save an MP4 file that's currently a resource file to a temp location that I can access as a path.
Here's something I've tried:
public static void WriteResourceToFile(string resourceName, string fileName)
{
using (Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
{
if (s != null)
{
byte[] buffer = new byte[s.Length];
char[] sb = new char[s.Length];
s.Read(buffer, 0, (int)(s.Length));
/* convert the byte into ASCII text */
for (int i = 0; i <= buffer.Length - 1; i++)
{
sb[i] = (char)buffer[i];
}
using (StreamWriter sw = new StreamWriter(fileName))
{
sw.Write(sb);
sw.Flush();
}
}
}}
You're overcomplicating it.
Try something like this (note, not compiled or tested, and Stream.CopyTo() only exists in .NET 4.0 and later).
using (Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)))
using (FileStream fs = File.Open("c:\myfile.mp4", FileMode.Create))
{
s.CopyTo(fs);
}
Job done.
If you don't have .NET 4.0 available, you'll need to implement one yourself, like one of these: How do I copy the contents of one stream to another?
To get a list of all of the resource names in the current assembly, do something like this:
Assembly a = Assembly.GetExecutingAssembly();
foreach (string s in a.GetManifestResourceNames())
{
Console.WriteLine(s);
}
Console.ReadKey();
Take what turns up on the console and pass it into GetManifestResourceStream() in the first snippet I posted.
http://msdn.microsoft.com/en-us/library/system.reflection.assembly.getmanifestresourcenames.aspx
Why are you writing an MP4 as a string? You should write out bytes without modification. Your conversion to chars is modifying the data. Use The FileStream call and call the Write method.
you could try something like this:
I pasted the wrong code in.... sorry, i was in a hurry
[HttpPost]
public ActionResult Create(VideoSermons video, HttpPostedFileBase videoFile)
{
var videoDb = new VideoSermonDb();
try
{
video.Path = Path.GetFileName(videoFile.FileName);
video.UserId = HttpContext.User.Identity.Name;
videoDb.Create(video);
if (videoFile != null && videoFile.ContentLength > 0)
{
var videoName = Path.GetFileName(videoFile.FileName);
var videoPath = Path.Combine(Server.MapPath("~/Videos/"),
System.IO.Path.GetFileName(videoFile.FileName));
videoFile.SaveAs(videoPath);
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
this actually loads video files to a directory, but it should work for your format as well.
-Thanks,

Categories