#nullable disable
using BLL.Controllers.Bases;
using BLL.DAL;
using BLL.Models;
using BLL.Services.Bases;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
// Generated from Custom Template.
namespace MVC.Controllers
{
[Authorize(Roles = "Admin")] // all of the actions can be executed for only logged in application users, who have an authentication cookie, with role name "Admin"
public class RolesController : MvcController // instead of inheriting from the Controller class, we inherit from the MvcController class to set the culture
{
// Service injections:
// Abstract Classes or Interfaces Way 1:
//private readonly IRoleService _roleService; // for role service Constructor Injection
// Abstract Classes or Interfaces Way 2:
private readonly IService<Role, RoleModel> _roleService; // for role service Constructor Injection
/* Can be uncommented and used for many to many relationships. {Entity} may be replaced with the related entiy name in the controller and views. */
//private readonly IService<{Entity}, {Entity}Model> _{Entity}Service;
// Object of type RoleService which is implemented from the IRoleService interface is injected to this class through the constructor,
// therefore role CRUD and other operations can be performed in the actions with _roleService field which references to the roleService injected instance.
public RolesController(
// Abstract Classes or Interfaces Way 1:
//IRoleService roleService
// Abstract Classes or Interfaces Way 2:
IService<Role, RoleModel> roleService
/* Can be uncommented and used for many to many relationships. {Entity} may be replaced with the related entiy name in the controller and views. */
//, IService<{Entity}, {Entity}Model> {Entity}Service
)
{
_roleService = roleService;
/* Can be uncommented and used for many to many relationships. {Entity} may be replaced with the related entiy name in the controller and views. */
//_{Entity}Service = {Entity}Service;
}
// GET: Roles
//[Authorize(Roles = "Admin")] // instead of using Authorize attribute above every action, it can be used above the controller and will execute for every action
public IActionResult Index()
{
// Get collection service logic:
var list = _roleService.Query().ToList(); // The role query is executed in the database and the result is stored
// in the collection of type List<RoleModel> when ToList method is called.
// ToList method can be used with any collection type to get a list such as
// IQueryable, DbSet, IEnumerable, ICollection, IList, List and arrays.
return View(list); // model of type List<RoleModel> will be passed to the Index view under Views/Roles folder
}
// GET: Roles/Details/5
//[Authorize(Roles = "Admin")] // instead of using Authorize attribute above every action, it can be used above the controller and will execute for every action
public IActionResult Details(int id)
{
// Get item service logic:
var item = _roleService.Query().SingleOrDefault(q => q.Record.Id == id); // gets the record of type RoleModel by id from the Roles table
return View(item); // sends item (model) of type RoleModel to the Views/Roles/Details.cshtml view
}
// The method for setting ViewData (ViewBag) to be sent to the views of the actions that return ViewResult (no redirection).
// ViewData collection is used to send extra data other than model data to the views.
// ViewData and ViewBag refers to the same collection and can be used interchangeably.
// We don't have any extra data other than RoleModel data to send the views in the actions, therefore we don't need to implement any code.
protected void SetViewData()
{
// Related items service logic to set ViewData (Record.Id and Name parameters may need to be changed in the SelectList constructor according to the model):
/* Can be uncommented and used for many to many relationships. {Entity} may be replaced with the related entiy name in the controller and views. */
//ViewBag.{Entity}Ids = new MultiSelectList(_{Entity}Service.Query().ToList(), "Record.Id", "Name");
}
// GET: Roles/Create
//[HttpGet] // action method which is get by default when not written, so we don't need to write this
//[Authorize(Roles = "Admin")] // instead of using Authorize attribute above every action, it can be used above the controller and will execute for every action
public IActionResult Create()
{
SetViewData();
return View(); // returning Create view under Views/Roles folder which contains a form, so that user can enter role data and submit it
}
// POST: Roles/Create
[HttpPost] // action method which is used for processing request data sent by a form or AJAX
[ValidateAntiForgeryToken] // attribute for preventing Cross-Site Request Forgery (CSRF)
//[Authorize(Roles = "Admin")] // instead of using Authorize attribute above every action, it can be used above the controller and will execute for every action
public IActionResult Create(RoleModel role) // the role data of type RoleModel that user enters in the Create view's form is submitted to this action
{
if (ModelState.IsValid) // validates the role action parameter (role model) through data annotations of its properties
{
// Insert item service logic: If role model data (Record) is valid, insert role service logic should be written here.
var result = _roleService.Create(role.Record); // We assign the result of the insert (create) operation to the result variable of type Service.
if (result.IsSuccessful) // If insert operation is successful, assign the result message to the TempData collection with key "Message"
// and redirect user to the Details action by sending the inserted role's Record.Id as parameter as the route value.
// Route values are always used as anonymous types.
// Anonymous types are the types for objects without any class implementations.
// Since there is a redirection here, we can't use ViewData (ViewBag) for carrying extra data to the view.
{
TempData["Message"] = result.Message; // Will be shown at the redirected view.
// Way 1: We can also redirect to the Index action to get to role list with the inserted role.
//return RedirectToAction("Index");
// Way 2: Showing user the details of the inserted role is a better approach.
//return RedirectToAction("Details", "Roles", new { id = role.Record.Id });
// Way 3: We don't need to send the controller name as second parameter, since we are redirecting within the RolesController.
return RedirectToAction(nameof(Details), new { id = role.Record.Id }); // nameof returns the name of the method, property, class, etc. as a string.
}
ModelState.AddModelError("", result.Message); // Error message to be shown in the validation summary of the view,
// this is a better approach instead of sending the error message with ViewBag (ViewData)
// to the view because we will need to implement the display of ViewBag in the view.
}
SetViewData();
return View(role); // Returning the role model containing the data entered by the user to the Create.cshtml view under Views/Roles folder
// therefore the user can correct validation errors without losing data of the form input elements.
}
// GET: Roles/Edit/5
//[Authorize(Roles = "Admin")] // instead of using Authorize attribute above every action, it can be used above the controller and will execute for every action
public IActionResult Edit(int id)
{
// Get item to edit service logic:
var item = _roleService.Query().SingleOrDefault(q => q.Record.Id == id); // getting the role model for editing from the service
SetViewData();
return View(item); // returning the role model to the view so that user can see the model data for editing
}
// POST: Roles/Edit
[HttpPost]
[ValidateAntiForgeryToken]
//[Authorize(Roles = "Admin")] // instead of using Authorize attribute above every action, it can be used above the controller and will execute for every action
public IActionResult Edit(RoleModel role) // the role data that user enters in the Edit view's form is submitted to this action
{
if (ModelState.IsValid) // if there are no validation errors through data annotations of the role model
{
// Update item service logic:
var result = _roleService.Update(role.Record); // update the role (Record) in the service
if (result.IsSuccessful) // if operation is successful, set operation result's message to TempData and
// redirect the user to the Details action with id assigned to Record.Id as route value
{
TempData["Message"] = result.Message;
return RedirectToAction(nameof(Details), new { id = role.Record.Id });
}
ModelState.AddModelError("", result.Message); // if operation is unsuccessful, carry error result message to the view's validation summary
}
SetViewData();
return View(role); // returning the role model sent by the user to the view so the user can correct the validation errors and try again
}
// GET: Roles/Delete/5
//[Authorize(Roles = "Admin")] // instead of using Authorize attribute above every action, it can be used above the controller and will execute for every action
public IActionResult Delete(int id)
{
// Get item to delete service logic:
var item = _roleService.Query().SingleOrDefault(q => q.Record.Id == id); // getting the role model to delete from the service
return View(item); // returning the role model to the view so that the user can see the details of the role
}
// POST: Roles/Delete
[HttpPost, ActionName("Delete")] // ActionName attribute (Delete) renames and overrides the action method name (DeleteConfirmed) for the route
// so that it can be requested as not Roles/DeleteConfirmed but as Roles/Delete.
[ValidateAntiForgeryToken]
//[Authorize(Roles = "Admin")] // instead of using Authorize attribute above every action, it can be used above the controller and will execute for every action
public IActionResult DeleteConfirmed(int id)
{
// Delete item service logic:
var result = _roleService.Delete(id); // deleting the role in the service by id
TempData["Message"] = result.Message; // setting TempData as the operation result
return RedirectToAction(nameof(Index)); // redirection to the Index action
}
}
}