Controller

 

As you know, an MVC controller is concerned with handling the HTTP requests/responses to deliver HTML to the client

The controller we use is the PhotosController this is in the MVC Controllers Folder

This should be very familiar to you, having the standard controller actions you would expect from a scaffolding operation.

There are some added features

  • A handler for autocomplete that returns Json to the search input
  • A handler for the Metadata page - see metadata
  • The Create handler not only creates a new record, it also handles image processing and there are some values you will want to change (see Jpeg Class)
  • The Delete handler not only deletes the photo record it also deletes all associated images
  • Edit also recalculates keywords and updates DateSaved (plus any user edited fields)
  • HiddenFilePath calculates an obfuscated file path.You should change the actual hidden folder name and the value here (currently set to Ph0t0gr@ph$). Also, set permissions to no access on this folder in IIS.

using Ben.Classes;
using Ben.Models;
using Microsoft.AspNet.Identity;
using NetImageGallery.Models;
using PagedList;
using System;
using System.Data;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Net;
using System.Web.Mvc;

namespace Ben.Controllers
{
    /// 
    /// Handles CRUD for the Photo table
    /// 
    /// Note: where you see the commented hash  #  it just means that it requires editing if using this controller as a template for another pagedtable        
    public class PhotosController : Controller
    {

        private ApplicationDbContext db = new ApplicationDbContext();

        /// 
        /// Page showing details of uploaded photos
        /// 
        /// a string to find contained in the name field
        /// for paged results
        /// a paged list to the index view or partial view if AJAX call
        [HttpGet]
        public ActionResult Index(string SearchTerm, int page = 1)
        {
            var model =
                     db.Photos
                    .Where(r => SearchTerm == null && r.Flag == false || r.Description.Contains(SearchTerm) && r.Flag == false) // #
                    .OrderByDescending(r => r.Id)
                .Select(r => new PhotoListViewModel // #
                {
                    Id = r.Id,
                    Creator = r.Creator,
                    SourceFilename = r.SourceFilename,
                    Description = r.Description,
                    Keywords = r.Keywords,
                    AspNetUserID = r.AspNetUserID,
                    ForeignKeyTable = r.ForeignKeyTable,
                    DateCreated = r.DateCreated,
                    DateSaved = r.DateSaved,
                    Count = r.Count,
                    Flag = r.Flag,
                    GUID = r.GUID,
                }).ToPagedList(page, 6);

            if (Request.IsAjaxRequest())
            {
                if (model.TotalItemCount == 1)
                {
                    return PartialView("_PhotosPartial", model); // #
                }
                else if (model.TotalItemCount == 0)
                {
                    return PartialView("_NoRecordsFound");
                }
                return PartialView("_PhotosPartial", model); // #
            }
            return View(model);
        }

        /// 
        /// for autocomplete functionality by the searchTerm INPUT on the Search page
        /// 
        /// search string to find records that contain this value
        /// 10 names as JSON
        public ActionResult Autocomplete(string term)
        {
            var model =
                   db.Photos
                   .Where(r => r.Description.Contains(term) && r.Flag == false) // #
                   .Take(10)
                   .Select(r => new
                   {
                       label = r.Description
                   });
            return Json(model, JsonRequestBehavior.AllowGet);
        }

        // GET: Photos/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Photo photo = db.Photos.Find(id);
            if (photo == null)
            {
                return HttpNotFound();
            }
            return View(photo);
        }

        public ActionResult Metadata(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Photo photo = db.Photos.Find(id);
            if (photo == null)
            {
                return HttpNotFound();
            }
            return View(photo);
        }


        // GET: Photos/Create
        public ActionResult Create()
        {
            return View();
        }

        /// 
        /// create a new photo record 
        /// 
        /// type PhotoCreateViewModel can contain an uploaded file of HttpPostedFileBase
        [HttpPost]
        [ValidateAntiForgeryToken]
        //[Authorize]
        public ActionResult Create(PhotoCreateViewModel model)
        {
            // to keep the photo.Id in scope - to roll back the new record if there is an error thrown
            int photoID = 0;

            try
            {
                if (ModelState.IsValid)
                {

                    Photo photo = new Photo
                    {
                        Creator = model.Creator ?? User.Identity.GetUserName(),
                        SourceFilename = "noImage.jpg",
                        Description = model.Description,
                        Keywords = model.Description.Keywords() + " " + model.Keywords,
                        AspNetUserID = User.Identity.GetUserId(),
                        ForeignKeyTable = model.ForeignKeyTable,
                        DateCreated = DateTime.Now,
                        DateSaved = DateTime.Now,
                        GUID = Guid.NewGuid()
                    };
                    db.Photos.Add(photo);
                    db.SaveChanges();
                    photoID = photo.Id;

                    if (model.UploadedFile != null) //save image
                    {
                        // This file is the original file, so will contain original metadata tags, as saved by native .net SaveAs() call
                        // model.UploadedFile.SaveAs(HiddenFilePath(photo));

                        // add metadata to uploaded image, then resize
                        using (Jpeg jpeg = new Jpeg(model.UploadedFile))
                        {
                            // EDIT TO MEET YOUR NEEDS
                            jpeg.Copyright = "www.bennysutton.com";
                            jpeg.Creator = photo.Creator;
                            jpeg.Country = "country not set";
                            jpeg.Headline = "headline not set";
                            jpeg.Keywords = photo.Keywords;
                            jpeg.Software = "ADz";
                            jpeg.Subject = photo.Description;
                            jpeg.Title = "Title not set";
                            jpeg.Save(HiddenFilePath(photo, false));

                            jpeg.ResizeAndSave(
                              "~/P/photos/thumbs/",
                              photo.Id.ToString() + ".jpg",
                               100);

                            jpeg.ResizeAndSave(
                               "~/P/photos/zoom/",
                               photo.Id.ToString() + ".jpg",
                            300);

                            jpeg.ResizeAndSave(
                              "~/P/photos/",
                              photo.Id.ToString() + ".jpg",
                                600);
                        }

                        photo.SourceFilename = model.UploadedFile.FileName;
                        db.SaveChanges();

                    }
                    return RedirectToAction("index");
                    // return RedirectToAction("Details", "Photos", new { id = photo.Id });
                }

            }
            catch (Exception e)
            {
                DeletePhoto(photoID);
                ModelState.AddModelError("", e.Message);
            }
            return View(model);
        }

        /// 
        /// Get the obfuscated full path, the directory name and filename combined, as either a virtual path or Physical path (default)
        /// 
        /// a photo object with one record
        /// either a virtual path or Physical path (default)
        /// 
        private string HiddenFilePath(Photo photo, bool returnPhysicalPath = true)
        {
            string saveToHiddenFolder = "~/P/" + PhotoFolders.Photo + "/";
            string saveToHiddenFileName = photo.Id.ToString() + "_" + photo.GUID + ".jpg";
            if (returnPhysicalPath)
            {
                return Path.Combine(saveToHiddenFolder, saveToHiddenFileName).PhysicalPathFromRootPath();
            }
            else
            {
                return Path.Combine(saveToHiddenFolder, saveToHiddenFileName);
            }
        }

        /// 
        /// delete a photo record and all associated image files
        /// 
        /// id of the record to delete
        // [Authorize(Roles = "Admin")]
        private void DeletePhoto(int photoID)
        {
            try
            {
                Photo photo = db.Photos.Find(photoID);
                if (photo != null)
                {
                    //  delete the images
                    System.IO.File.Delete(HiddenFilePath(photo)); // Original
                    System.IO.File.Delete(Path.Combine("~/P/photos/thumbs/", photo.Id.ToString() + ".jpg").PhysicalPathFromRootPath()); // Thumb
                    System.IO.File.Delete(Path.Combine("~/P/photos/zoom/", photo.Id.ToString() + ".jpg").PhysicalPathFromRootPath());  // Zoom
                    System.IO.File.Delete(Path.Combine("~/P/photos/", photo.Id.ToString() + ".jpg").PhysicalPathFromRootPath());        //  Large

                    db.Photos.Remove(photo);
                    db.SaveChanges();
                }
            }
            catch (Exception)
            {
            }
        }

        // GET: Photos/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Photo photo = db.Photos.Find(id);
            if (photo == null)
            {
                return HttpNotFound();
            }
            return View(photo);
        }

        /// 
        /// Edit the photo database record by HTTP POST from the edit form
        /// 
        /// the id of the record to edit
        /// note: the photo images are left untouched
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Id,Creator,Description,Keywords,SourceFilename,AspNetUserID,ForeignKeyTable,DateCreated,DateSaved,Flag,Count,GUID")] Photo photo)
        {
            if (ModelState.IsValid)
            {
                db.Entry(photo).Property("Keywords").CurrentValue = String.Join(" ", db.Entry(photo).Property("Keywords").CurrentValue, db.Entry(photo).Property("Description").CurrentValue).Keywords();
                db.Entry(photo).Property("DateSaved").CurrentValue = DateTime.Now;

                db.Entry(photo).State = EntityState.Modified;
                db.Entry(photo).Property("SourceFilename").IsModified = false;
                db.Entry(photo).Property("AspNetUserID").IsModified = false;
                db.Entry(photo).Property("ForeignKeyTable").IsModified = false;
                db.Entry(photo).Property("DateCreated").IsModified = false;
                db.Entry(photo).Property("Count").IsModified = false;
                db.Entry(photo).Property("GUID").IsModified = false;
                db.SaveChanges();
            }
            return RedirectToAction("Index");
        }

        // GET: Photos/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Photo photo = db.Photos.Find(id);
            if (photo == null)
            {
                return HttpNotFound();
            }
            return View(photo);
        }

        // POST: Photos/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            DeletePhoto(id);
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

    
Next >>>