0

When I delete a record from my database everything is deleted except the image file from the folder.

In the Save Action I have the upload method that is working fine. The DeleteConfirmed Action works only for deleting the records and not the image file and when I hit the delete button that I will show you in my view a get an access denied. The project works on IIS Express if that is an option. Is there some other way of deleting the specific file which is attached to the record?

Note that the image is stored on the ArticleImage string which is in the BlogArticle class.

Here is my Controller that handles the actions that save the records.

Controller

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using SkylineNew.Models;
using SkylineNew.ViewModel;
using BlogArticle = SkylineNew.Models.BlogArticle;

namespace SkylineNew.Controllers
{
    public class BlogArticleController : Controller
    {
        private SkylineNewDbContext _context;

        public BlogArticleController()
        {
            _context = new SkylineNewDbContext();
        }

        protected override void Dispose(bool disposing)
        {
            _context.Dispose();
        }

        [Authorize(Roles = RoleName.CanManageEverything)]
        public ViewResult New()
        {
            var tags = _context.Tags.ToList();

            var viewModel = new BlogArticleViewModel
            {
                BlogArticles = new BlogArticle(),
                Tags = tags
            };

            return View("BlogArticleForm", viewModel);
        }

        public ViewResult Blog()
        {
            if (User.IsInRole("CanManageEverything"))
            {
                var blg = _context.BlogArticles.Include(b => b.Tags).ToList();

                return View("Blog", blg);
            }
            else
            {
                var blg = _context.BlogArticles.Include(b => b.Tags).ToList();

                return View("BlogReadOnly", blg);
            }
        }

        public ActionResult Details(int Id)
        {
            var blg = _context.BlogArticles.Include(b => b.Tags).SingleOrDefault(b => b.Id == Id);

            if (blg == null)
                return HttpNotFound();

            return View(blg);

        }

        [Authorize(Roles = RoleName.CanManageEverything)]
        public ActionResult Edit(int id)
        {
            var blgs = _context.BlogArticles.Include(b => b.Tags).SingleOrDefault(b => b.Id == id);

            if (blgs == null)
                return HttpNotFound();

            var viewModel = new BlogArticleViewModel(blgs)
            {
                BlogArticles = blgs,
                Tags = _context.Tags.ToList()
            };

            return View("BlogArticleForm", viewModel);
        }

        //GET : BlogArticles

        [HttpGet]
        [Authorize(Roles = RoleName.CanManageEverything)]
        public ActionResult Save()
        {
            BlogArticle blg = new BlogArticle();
            return RedirectToAction("Blog", "BlogArticle", blg);
        }

        //POST : BlogArticles

        [HttpPost]
        [ValidateAntiForgeryToken]
        [ValidateInput(false)]
        [Authorize(Roles = RoleName.CanManageEverything)]
        public ActionResult Save(BlogArticle blg, string articleImage, HttpPostedFileBase imageFile)
        {
            if (!ModelState.IsValid)
            {
                var viewModel = new BlogArticleViewModel(blg)
                {
                    BlogArticles = blg,
                    Tags = _context.Tags.ToList()
                };

                return View("BlogArticleForm", viewModel);
            }

            if (imageFile == null)
            {
                ModelState.AddModelError("MovieImage", "Παρακαλώ ανεβάστε μία εικόνα άρθρου.");
            }

            // Upload Image //

            if (imageFile != null)
            {
                articleImage = Path.GetFileNameWithoutExtension(imageFile.FileName);
                string extension = Path.GetExtension(imageFile.FileName);
                articleImage = articleImage + DateTime.Now.ToString("yymmssfff") + extension;
                blg.ArticleImage = "~/images/BlogImages/" + articleImage;
                articleImage = Path.Combine(Server.MapPath("~/images/BlogImages/") + articleImage);
                imageFile.SaveAs(articleImage);
            }

            if (blg.Id == 0)
            {
                blg.DateAdded = DateTime.Now;
                _context.BlogArticles.Add(blg);
            }

            else
            {
                var blginDb = _context.BlogArticles.Single(b => b.Id == blg.Id);

                blginDb.ArticleTitle = blg.ArticleTitle;
                blginDb.ArticleText = blg.ArticleText;
                blginDb.ArticleSource = blg.ArticleSource;
                blginDb.ArticleIntro = blg.ArticleIntro;
                blginDb.ArticleImage = blg.ArticleImage;
                blginDb.TagsId = blg.TagsId;
            }

            _context.SaveChanges();
            return RedirectToAction("Blog", "BlogArticle");
        }

        //GET : BlogArticles/Delete

        [HttpGet]
        [Authorize(Roles = RoleName.CanManageEverything)]
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            BlogArticle blg = _context.BlogArticles.Find(id);

            if (blg == null)
            {
                return HttpNotFound();
            }
            return View(blg);
        }

        // POST: BlogArticles/Delete/

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        [Authorize(Roles = RoleName.CanManageEverything)]
        public ActionResult DeleteConfirmed(BlogArticle blg, int id, string imageFile)
        {
            imageFile = "";
            string path = Server.MapPath(@"~/images/BlogImages/" + imageFile);

            System.IO.File.SetAttributes(path, FileAttributes.Normal);
            System.IO.File.Delete(path);

            blg = _context.BlogArticles.Find(id);

            _context.BlogArticles.Remove(blg);
            _context.SaveChanges();

            return RedirectToAction("Blog", "BlogArticle");
        }
    }
}

Class

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;

namespace SkylineNew.Models
{
    public class BlogArticle
    {
        public int Id { get; set; }

        [Required(ErrorMessage = "Παρακαλώ εισάγετε το κείμενο του άρθρου")]
        [Display(Name = "Κείμενο")]
        public string ArticleText { get; set; }

        [Required(ErrorMessage = "Παρακαλώ εισάγετε τον τίτλο του άρθρου")]
        [Display(Name = "Τίτλος")]
        public string ArticleTitle { get; set; }

        [Required(ErrorMessage = "Παρακαλώ εισάγετε την πηγή του άρθρου")]
        [Display(Name = "Πηγή")]
        public string ArticleSource { get; set; }

        [Display(Name = "Εικόνα Άρθρου")]
        public string ArticleImage { get; set; }

        [Required(ErrorMessage = "Παρακαλώ εισάγετε την περίληψη του άρθρου")]
        [Display(Name = "Περίληψη κειμένου")]
        public string ArticleIntro { get; set; }

        public DateTime DateAdded { get; set; }

        public Tags Tags { get; set; }

        [Required(ErrorMessage = "Παρακαλώ εισάγετε ετικέτες.")]
        [Display(Name = "Ετικέτες")]
        public byte TagsId { get; set; }
    }
}

Web.Config

<?xml version="1.0" encoding="utf-8"?>
<!--
 For more information on how to configure your ASP.NET application, please visit
https://go.microsoft.com/fwlink/?LinkId=301880
-->

<configuration>
    <configSections>
        <!-- For more information on Entity Framework configuration, visit  http://go.microsoft.com/fwlink/?LinkID=237468 -->
        <section name="entityFramework"  type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection,  EntityFramework, Version=6.0.0.0, Culture=neutral,  PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </configSections>
    <connectionStrings>
        <add name="SkylineNewDB" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\SkylineNewDB.mdf;Initial Catalog=SkylineNewDB;Integrated Security=True" providerName="System.Data.SqlClient" />
    </connectionStrings>
    <appSettings>
        <add key="webpages:Version" value="3.0.0.0" />
        <add key="webpages:Enabled" value="false" />
        <add key="ClientValidationEnabled" value="true" />
        <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    </appSettings>
    <system.web>
        <compilation debug="true" targetFramework="4.6.1" />
        <httpRuntime targetFramework="4.6.1" />
        <httpModules>
            <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
        </httpModules>
    </system.web>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <dependentAssembly>
            <assemblyIdentity name="Antlr3.Runtime" publicKeyToken="eb42632606e9261f" />
            <bindingRedirect oldVersion="0.0.0.0-3.5.0.2" newVersion="3.5.0.2" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" />
            <bindingRedirect oldVersion="0.0.0.0-4.0.2.1" newVersion="4.0.2.1" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
            <bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-5.2.4.0" newVersion="5.2.4.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
          </dependentAssembly>
        </assemblyBinding>
    </runtime>
    <system.webServer>
        <modules>
            <remove name="TelemetryCorrelationHttpModule" />
            <add name="TelemetryCorrelationHttpModule" type="Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule, Microsoft.AspNet.TelemetryCorrelation" preCondition="integratedMode,managedHandler" />
            <remove name="ApplicationInsightsWebTracking" />
            <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
        </modules>
        <validation validateIntegratedModeConfiguration="false" />
    </system.webServer>
    <system.codedom>
        <compilers>
            <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.8.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
            <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.8.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
        </compilers>
    </system.codedom>
    <entityFramework>
        <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
            <parameters>
                <parameter value="mssqllocaldb" />
            </parameters>
        </defaultConnectionFactory>
        <providers>
            <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
        </providers>
    </entityFramework>
</configuration>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131

2 Answers2

0

For your ActionResult DeleteConfirmed, I would add a Try statement to catch any failure and I would also check, if the file exists before trying to delete it:

try
    {
        if (System.IO.File.Exists(path))
        {
            System.IO.File.SetAttributes(path, FileAttributes.Normal);
            System.IO.File.Delete(path);
        }
    }
    catch (Exception e)
        {
            // Handle error
        }

The "access denied" you are getting sounds like the user account that is running your website, has not got enough authority to delete the file in the folder specified. You would need to review the security on the hosting server.

rBalzer
  • 347
  • 1
  • 7
  • Its the same. I don't get the access denied but the physical file won't be deleted. The problem is how to declare the physical file to string that gets the filename per record on the database? in this case the ArticleImage – Μιχαηλ Τσιγαρας Aug 31 '18 at 10:36
0

I just found the solution!!!!

So in the controller in the DeleteConfirmed Action I just made some changes.

 [HttpPost, ActionName("Delete")]
    [ValidateAntiForgeryToken]
    [Authorize(Roles = RoleName.CanManageEverything)]
    public ActionResult DeleteConfirmed(BlogArticle blg, int id)
    {                      
        blg = _context.BlogArticles.Find(id);

        _context.BlogArticles.Remove(blg);

        System.IO.File.Delete(Request.MapPath(blg.ArticleImage));

        _context.SaveChanges();

        return RedirectToAction("Blog", "BlogArticle");
    }