How to save image path in database and save image in specific folder of project.NET core - asp.net-core-mvc

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Employee emp)
{
if (ModelState.IsValid)
{
var files = HttpContext.Request.Form.Files;
foreach (var Image in files)
{
if (Image != null && Image.Length > 0)
{
var file = Image;
var root = _appEnvironment.WebRootPath;
var uploads = "uploads\\img";
if (file.Length > 0)
{
// you can change the Guid.NewGuid().ToString().Replace("-", "")
// to Guid.NewGuid().ToString("N") it will produce the same result
var fileName = Guid.NewGuid().ToString("N") + Path.GetExtension(file.FileName);
using (var fileStream = new FileStream(Path.Combine(root, uploads, fileName), FileMode.Create))
{
await file.CopyToAsync(fileStream);
// This will produce uploads\img\fileName.ext
emp.ImageUrl = Path.Combine(uploads, fileName);
}
}
}
}
db.Add(emp);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
else
{
var errors = ModelState.Values.SelectMany(v => v.Errors);
}
return View(emp);
}
HTML
<input asp-for="ImageUrl" type="file" Class="form-control" />
when i save image, image save successfully in database, but it takes full image path like this C:\Users\VIZO\Desktop\employee.jpg i dont want like this, i need to save image path something like this ~images\employee.jpg. The other problem is image doesnt saving in specific folder of project, i need to save image in this path of my project
uploads\img

So basically your _appEnvironment.WebRootPath by default will be:
%PathToProject%/wwwroot.
For the filePath on your database i would do something like this:
var root = _appEnvironment.WebRootPath
var uploads = "uploads\\img";
if (file.Length > 0)
{
// you can change the Guid.NewGuid().ToString().Replace("-", "")
// to Guid.NewGuid().ToString("N") it will produce the same result
var fileName = Guid.NewGuid().ToString("N") + Path.GetExtension(file.FileName);
using (var fileStream = new FileStream(Path.Combine(root, uploads, fileName), FileMode.Create))
{
await file.CopyToAsync(fileStream);
// This will produce uploads\img\fileName.ext
emp.BookPic = Path.Combine(uploads, fileName);
}
}
If you require any more clarification or guidance please feel free to comment and allow me to explain in more detail.
Thanks.

Related

Image in ASP.NET MVC

I have form for upload file and i want to upload thumbnail for the file in the same form I am doing that with this part of code :
var basePath2 = Path.Combine(Directory.GetCurrentDirectory() + "\\Thumbnails\\");
bool basePathExists2 = System.IO.Directory.Exists(basePath2);
if (!basePathExists2)
Directory.CreateDirectory(basePath2);
var thumbnailPath = Path.Combine(basePath2, Thumbnail.FileName);
if (!System.IO.File.Exists(thumbnailPath))
{
using (var stream = new FileStream(thumbnailPath, FileMode.Create))
{
await Thumbnail.CopyToAsync(stream);
}
}
I am saving this model to the database:
var fileModel = new FileUploadViewModel
{
Year = createdOn,
PublishedOn = model.PublishedOn,
FileType = File.ContentType,
Extension = extension,
Name = model.Name,
Description = model.Description,
FilePath = filePath,
Author = model.Author,
ThumbnailPath = thumbnailPath,
};
When I want to show the thumbnail in a view, it doesn't work but in src I have the right path, as you can see in this screenshot:
Screenshot with Source of image
In controller :
string uniqueThumbName = null;
if (Thumbnail != null)
{
string uploadsFolder = Path.Combine(hostingEnvironment.WebRootPath, "Thumbnails");
uniqueThumbName=Guid.NewGuid().ToString() + "_" + Thumbnail.FileName;
string filePath2 = Path.Combine(uploadsFolder, uniqueThumbName);
Thumbnail.CopyTo(new FileStream(filePath2, FileMode.Create));
}
var fileModel = new FileUploadViewModel
{
ThumbnailPath=uniqueThumbName,
};
In View :
var thumbPath = "~/Thumbnails/" + file.ThumbnailPath;
<img style="width:80px;height:80px;" src="#thumbPath" asp-append-version="true" />

Rename a recorded file every time I save a record in xamarin

I am saving my records using this code:
string path = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
public string fileName { get; set; }
fileName = Path.Combine(path, "sample.wav");
if (!recorder.IsRecording)
{
recorder.StopRecordingOnSilence = TimeoutSwitch.IsToggled;
//Start recording
var audioRecordTask = await recorder.StartRecording();
BtnDoneRec.IsEnabled = false;
await audioRecordTask;
RecEditor.IsEnabled = true;
BtnDoneRec.IsEnabled = false;
PlayButton.IsEnabled = true;
var filePath = recorder.GetAudioFilePath();
if (filePath != null)
{
var stream = recorder.GetAudioFileStream();
using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
stream.CopyTo(fileStream);
}
}
}
else
{
//stop recording ...
await recorder.StopRecording();
}
I want my record to have a specific name which is labeled with my RecEditor
using (var streamReader = new StreamReader(fileName))
{
File.Move("sample.wav", RecEditor.Text + ".wav");
}
So it will rename "sample.wav" to "RecEditor text.wav" every time I click my save button.
But when I click save, it gives me this record
System.IO.FileNotFoundException: 'Could not find file '/sample.wav'.'
The record is stored in /storage/emulated/0/sample.wav
The sample.wav is created in my device but I don't know why it give me 'Could not find file '/sample.wav'.' error. What am i doing wrong here?
I believe that what you're looking is something like this:
if(File.Exists(fileName))
{
var newFileName = Path.Combine(path, $"{RecEditor.Text}.wav");
File.Move(fileName, newFileName);
}
You don't need to open a new Stream as you are doing. Also, you need to put the full file path not only the file name.
You might want to validate that RecEditor.Text is not empty before using its value for the newfileName
Hope this helps.-

Android post image to Facebook comment

This is a followup to my previous question: Xamarin.Forms App return data to calling App
That works perfectly and I can share images to anywhere, except to Facebook comments. When I click the camera on the content box the app can be selected, I can select the image, Set result and Finish are called, and the app closes and it sends data to Facebook, and then however I then get the error : The image could not be uploaded, try again?
I can't find any fundamental differences between posting to a status or a comment, so I'm guessing it's subtle. Any thoughts on how I can change my intent to post properly?
Adding for completeness:
Bitmap b = null;
string url;
if (!string.IsNullOrEmpty(this.saleItems[i].ImageUrl))
{
url = this.saleItems[i].ImageUrl;
}
else
{
url = await FileHelper.GetLocalFilePathAsync(this.saleItems[i].Id);
}
//download
using (var webClient = new WebClient())
{
var imageBytes = webClient.DownloadData(url);
if (imageBytes != null && imageBytes.Length > 0)
{
b = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
}
}
//set local path
var tempFilename = "test.png";
var sdCardPath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
var filePath = System.IO.Path.Combine(sdCardPath, tempFilename);
using (var os = new FileStream(filePath, FileMode.Create))
{
b.Compress(Bitmap.CompressFormat.Png, 100, os);
}
b.Dispose();
var imageUri = Android.Net.Uri.Parse($"file://{sdCardPath}/{tempFilename}");
var sharingIntent = new Intent();
sharingIntent.SetAction(Intent.ActionSend);
sharingIntent.SetType("image/*");
sharingIntent.PutExtra(Intent.ExtraText, "some txt content");
sharingIntent.PutExtra(Intent.ExtraStream, imageUri);
sharingIntent.AddFlags(ActivityFlags.GrantReadUriPermission);
//await SaleItemDataService.Instance.BuySaleItemAsync(this.saleItem);
SetResult(Result.Ok, sharingIntent);
Finish();
Use below:
Intent sharingIntent = new Intent();
string imageUri = "file://" + requestedUri;
sharingIntent.SetData(Android.Net.Uri.Parse(imageUri));

Image Upload doesn't work in Server. Works fine in localhost

So, this code works just fine in localhost. It deletes the previous image and uploads the new one. It does nothing on server however. Any clue?
I have used AJAX for asynchorous call By the way if that makes a difference.
var db=Database.Open("StarterSite");
var contentQuery="Select * from Contents where id =#0";
var content=db.QuerySingle(contentQuery,"1");
var message="";
var imgCount=0;
var alreadyExist=false;
try{
if (IsPost && Request.Files.Count > 0) {
bool deleteSuccess = false;
var fileName = "";
var photoName = "";
var fileSavePath = "";
var uploadedFile = Request.Files[0];
var toDelete=Request["toDelete"];
var toUpload=Request["toUpload"];
if(uploadedFile.ContentLength>0){
#******************DELETE***************#
var fullPath = Server.MapPath("~/img/" + toDelete);
if (File.Exists(fullPath))
{
File.Delete(fullPath);
deleteSuccess = true;
}
#****************UPLOAD*******************#
fileName = Path.GetFileName(uploadedFile.FileName);
fileSavePath = Server.MapPath("~/img/" +
fileName);
uploadedFile.SaveAs(fileSavePath);
var updateQuery="Update Contents Set "+toUpload +"=#0";
db.Execute(updateQuery, fileName);
//Response.Redirect("editMode.cshtml");
}
}
}
catch(HttpException ex){
message="Image size you selected was too large. Please select a different Image.";
}
Try changing the permission of the folder to 777.

MVC4 exception when saving HttpPostedFileBase for the second time

in my ASP.NET MVC4 project I need a way to upload a picture that gets saved to a folder on the server. I came up with the controller code below: it basically works, but only for the first time! When calling this method again (with the same TeacherId to set a new image), I get a System.IO.IOException (HResult -2147024864) that tells me, that the file is in use by another process. How can I avoid the locking? And why does it actually work in the first place? I tidy up all images and streams, but it seams I'm somehow missing something important. Thanks you for your help!
[HttpPost]
public ActionResult Upload(HttpPostedFileBase pic, int TeacherId)
{
if (pic.ContentLength > 0) {
var fileName = "Teacher" + TeacherId.ToString() + "tmp.jpg";
var path = Path.Combine(Server.MapPath("~/TempImages"), fileName);
Image i = Image.FromStream(pic.InputStream, true, true);
if (i.Size.Width > 700 || i.Height > 700)
{
Image resizedImage;
resizedImage = ResizeImage(i, new Size { Width = 700, Height = 700 }, true);
i.Dispose();
resizedImage.Save(path,ImageFormat.Jpeg);
resizedImage.Dispose();
}
else
{
i.Dispose();
}
pic.InputStream.Close();
pic.InputStream.Dispose();
TempData["TeacherId"] = TeacherId.ToString();
return RedirectToAction("EditImage", new { TeacherId = TeacherId });
}
return RedirectToAction("UploadImage", new { TeacherId = TeacherId });
}

Resources