You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iot/projects/Infrastructure/Web/Mvc/CrudController.cs

277 lines
8.6 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using Infrastructure.Application;
using Infrastructure.Data;
using Infrastructure.Domain;
using Infrastructure.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
namespace Infrastructure.Web.Mvc
{
public class CrudController<TEntity, TSearchModel, TDisplayModel, TEditModel> : BaseController
where TEntity : BaseEntity
where TSearchModel : PagedListModel<TDisplayModel>
{
private readonly IRepository<TEntity> _repo;
public CrudController(IRepository<TEntity> repo)
{
this._repo = repo;
}
public virtual IActionResult Index(TSearchModel model)
{
var query = this._repo.ReadOnlyTable();
if (!model.IsDeleted)
{
query = query.Where(o => !o.IsDeleted);
}
query = this.Include(query);
query = this.Query(model, query);
query = query.OrderBy(o => o.DisplayOrder).ThenBy(o => o.Id);
model.TotalCount = query.Count();
model.List = query.Skip(model.PageSize * (model.PageIndex - 1))
.Take(model.PageSize)
.ToList()
.Select(o =>
{
var m = o.To<TDisplayModel>();
this.ToDisplayModel(o, m);
return m;
})
.ToList();
ViewData["EntityTypeExt"] = typeof(TEntity);
ViewData["ModelTypeExt"] = typeof(TDisplayModel);
return View(model);
}
public virtual IActionResult Details(Guid id)
{
var query = this._repo.ReadOnlyTable();
query = this.Include(query);
var entity = query.FirstOrDefault(o => o.Id == id);
var model = entity.To<TEditModel>();
this.ToModel(entity, model);
return View(model);
}
public virtual IActionResult Add()
{
var model = Activator.CreateInstance<TEditModel>();
this.ToModel(null, model);
return View(model);
}
[HttpPost]
public virtual IActionResult Add(TEditModel model)
{
if (ModelState.IsValid)
{
try
{
var entity = Activator.CreateInstance<TEntity>();
entity.From(model);
this.ToEntity(model, entity);
this._repo.Add(entity);
this._repo.SaveChanges();
this.OnAdded(entity);
return RedirectTo();
}
catch (Exception ex)
{
ex.PrintStack();
ModelState.AddModelError("", ex.Message);
}
}
this.ToModel(null, model);
return View(model);
}
public virtual void OnAdded(TEntity entity)
{
}
public virtual IActionResult Edit(Guid id)
{
var query = this._repo.ReadOnlyTable();
query = this.Include(query);
var entity = query.FirstOrDefault(o => o.Id == id);
var model = entity.To<TEditModel>();
this.ToModel(entity, model);
return View(model);
}
[HttpPost]
public virtual IActionResult Edit(TEditModel model)
{
var id = (Guid)model.GetType().GetProperty("Id").GetValue(model);
var query = this._repo.Table();
query = this.Include(query);
var entity = query.FirstOrDefault(o => o.Id == id);
if (ModelState.IsValid)
{
try
{
this.OnEdit(entity, model);
entity.From(model);
this.ToEntity(model, entity);
this._repo.SaveChanges();
this.OnUpdeted(entity);
return RedirectTo();
}
catch (Exception ex)
{
ex.PrintStack();
ModelState.AddModelError("", ex.Message);
}
}
this.ToModel(entity, model);
return View(model);
}
public virtual void OnUpdeted(TEntity entity)
{
}
public virtual IActionResult Remove(List<Guid> list)
{
try
{
foreach (var id in list)
{
var query = this._repo.Table();
var entity = query.FirstOrDefault(o => o.Id == id);
entity.IsDeleted = true;
this._repo.SaveChanges();
}
return RedirectTo();
}
catch (Exception ex)
{
ex.PrintStack();
return RedirectTo(message: ex.Message);
}
}
public IActionResult Restore(List<Guid> list)
{
try
{
foreach (var id in list)
{
var query = this._repo.Table();
var entity = query.FirstOrDefault(o => o.Id == id);
entity.IsDeleted = false;
this._repo.SaveChanges();
}
return RedirectTo();
}
catch (Exception ex)
{
ex.PrintStack();
return RedirectTo(message: ex.Message);
}
}
public virtual IActionResult Delete(List<Guid> list)
{
try
{
foreach (var id in list)
{
var query = this._repo.Table();
var entity = query.FirstOrDefault(o => o.Id == id);
this._repo.Delete(entity);
this._repo.SaveChanges();
this.OnDeleted(entity);
}
return RedirectTo();
}
catch (Exception ex)
{
ex.PrintStack();
return RedirectTo(message: ex.Message);
}
}
public virtual void OnDeleted(TEntity entity)
{
}
public virtual IQueryable<TEntity> Include(IQueryable<TEntity> query)
{
return query;
}
public virtual IQueryable<TEntity> Query(TSearchModel model, IQueryable<TEntity> query)
{
return query;
}
public virtual void ToModel(TEntity entity, TEditModel model)
{
}
public virtual void ToDisplayModel(TEntity entity, TDisplayModel model)
{
}
public virtual void ToEntity(TEditModel model, TEntity entity)
{
}
public virtual void OnEdit(TEntity entity, TEditModel model)
{
}
public override void OnActionExecuting(ActionExecutingContext context)
{
var name = (context.ActionDescriptor as ControllerActionDescriptor).ActionName;
var permission = string.Empty;
if (name == "Index")
{
permission = $"List{typeof(TEntity).Name}";
}
else if (name == "Details")
{
permission = $"Read{typeof(TEntity).Name}";
}
else if (name == "Add")
{
permission = $"Add{typeof(TEntity).Name}";
}
else if (name == "Edit")
{
permission = $"Edit{typeof(TEntity).Name}";
}
else if (name == "Remove")
{
permission = $"Edit{typeof(TEntity).Name}";
}
else if (name == "Restore")
{
permission = $"Edit{typeof(TEntity).Name}";
}
else if (name == "Delete")
{
permission = $"Delete{typeof(TEntity).Name}";
}
if (!string.IsNullOrEmpty(permission))
{
var returnUrl = context.HttpContext.Request.GetUrl();
if (!context.HttpContext.User.Identity.IsAuthenticated)
{
context.Result = new RedirectToActionResult("Login", "Account", new { area = "", returnUrl }); ;
}
else if (!context.HttpContext.User.IsInRole(permission))
{
context.Result = new RedirectToActionResult("AccessDenied", "Account", new { area = "", returnUrl });
}
}
}
}
}