Reputation: 305
I am using ASP.Net Core with MVC for creating an app. I am using visual studio and IIS express currently. Below is my current project structure:
*project directory
-wwwroot
-areas
-attachments
-controllers
-models
-views
I currently store images inside the attachments folder.
Previously I have written something like that inside my startup.cs
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "Attachments")),
RequestPath = "/Attachments"
});
I have also done something like this below:
appendImage(@Url.Content("~/Attachments/")+result.fileName);
I did this to display an image on my view. The image is displayed successfully.
What I am trying to achieve now is the on the UI allow the user to make a choice to delete the files inside that attachments folder
I tried the following code:
string contentRootPath = _hostingEnvironment.ContentRootPath;
string fullImagePath = Path.Combine(contentRootPath + "\\Attachments", currentItemToDelete.FileName);
if (System.IO.File.Exists(fullImagePath))
{
try{
System.IO.File.Delete(fullImagePath);
}catch(Exception e){
operationResult = "Attachment Path. Internal Server Error";
}
}
The execution does enter the if (System.IO.File.Exists(fullImagePath))
but it raises an exception when it reaches System.IO.File.Delete
. The exception states that the file which resides in that path is being used by another process. And thus I cannot delete the file. The only process that is accessing the file is the web app I am creating/debugging at the same time. How do I prevent this exception from happening? Do I have to use other kind of code to delete the file ?
EDIT to include more details:
Inside my view(index.cshtml):
appendImage is a javascript function:
function appendImage(imgSrc) {
var imgElement = document.createElement("img");
imgElement.setAttribute('src', imgSrc);
if (imgSrc.includes(null)) {
imgElement.setAttribute('alt', '');
}
imgElement.setAttribute('id', "img-id");
var imgdiv = document.getElementById("div-for-image");
imgdiv.appendChild(imgElement);
}
That function is called below:
$.ajax({
url:'@Url.Action("GetDataForOneItem", "Item")',
type: "GET",
data: { id: rowData.id },
success: function (result) {
removeImage();
appendImage(@Url.Content("~/Attachments/")+result.fileName);
$("#edit-btn").attr("href", '/Item/EditItem?id=' + result.id);
},
error: function (xhr, status, error) {
}
});
After calling appendImage(); I change the href of a <a>
tag. When the user clicks on the link, the user is directed to another page(edit.cshtml). In the page, the image which resides in that path is also being displayed with code like this:
<img src="@Url.Content("~/Attachments/"+Model.FileName)" alt="item image" />
In this new page(edit.cshtml), there is a delete button. Upon clicking the delete button, the execution of the program goes to the controller which is this controller function:
[HttpPost]
public string DeleteOneItem(int id)
{
//query the database to check if there is image for this item.
var currentItemToDelete = GetItemFromDBDateFormatted(id);
if (!string.IsNullOrEmpty(currentItemToDelete.FileName))
{
//delete the image from disk.
string contentRootPath = _hostingEnvironment.ContentRootPath;
string fullImagePath = Path.Combine(contentRootPath + "\\Attachments", currentItemToDelete.FileName);
if (System.IO.File.Exists(fullImagePath))
{
try
{
System.IO.File.Delete(fullImagePath);
}catch(Exception e)
{
}
}
}
return "";
}
EDIT to answer question:
Add in
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
before system.io.file.delete
Upvotes: 4
Views: 4737
Reputation: 215
you can replace your C# method DeleteOneItem with this given code. may be it might work.
[HttpPost]
public string DeleteOneItem(int id)
{
//query the database to check if there is image for this item.
var currentItemToDelete = GetItemFromDBDateFormatted(id);
if (!string.IsNullOrEmpty(currentItemToDelete.FileName))
{
//delete the image from disk.
string contentRootPath = _hostingEnvironment.ContentRootPath;
string fullImagePath = Path.Combine(contentRootPath + "\\Attachments", currentItemToDelete.FileName);
if (System.IO.File.Exists(fullImagePath))
{
try
{
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.IO.File.Delete(fullImagePath);
}
catch (Exception e) { }
}
}
return "";
}
Upvotes: 7
Reputation: 305
try
{
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.IO.File.Delete(fullImagePath);
}
catch(Exception e){
}
Upvotes: 6