Skip to content

Instantly share code, notes, and snippets.

@WrackedFella
Last active April 20, 2018 16:40
Show Gist options
  • Save WrackedFella/c5aff0f5389ed331ecde4b91d7783f77 to your computer and use it in GitHub Desktop.
Save WrackedFella/c5aff0f5389ed331ecde4b91d7783f77 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using MyProject.Api.ExceptionHandling.CustomExceptions;
using MyProject.Api.SearchModels;
using MyProject.Dal.Core;
namespace MyProject.Api.Core
{
[Route("api/[controller]")]
public abstract class BaseController : Controller
{
protected readonly string AuditUser;
protected readonly DbContext Context;
protected BaseController(DbContext context, IHttpContextAccessor accessor)
{
this.Context = context;
this.AuditUser = accessor.HttpContext.User.Identity.Name;
}
}
// Without Search
[Route("api/[controller]")]
public abstract class BaseController<TEntity, TModel> : Controller
where TEntity : BaseEntity
where TModel : BaseModel
{
protected readonly string AuditUser;
protected readonly DbContext Context;
protected BaseController(DbContext context, IHttpContextAccessor accessor)
{
this.Context = context;
this.AuditUser = accessor.HttpContext.User.Identity.Name;
}
[Route("get")]
[HttpGet]
public virtual async Task<TModel> Get(int id)
{
var result = await this.Context.Set<TEntity>().FindAsync(id);
return Mapper.Map<TModel>(result);
}
[Route("list")]
[HttpGet]
public virtual async Task<IEnumerable<TModel>> List()
{
return await this.Context.Set<TEntity>().ProjectTo<TModel>().ToListAsync();
}
[Route("search")]
[HttpPost]
public virtual async Task<IEnumerable<TModel>> Search([FromBody] object model)
{
throw new NotImplementedException();
}
[Route("createupdate")]
[HttpPost]
public virtual async Task<int> CreateUpdate([FromBody] TModel model)
{
// ToDo: Handle duplicate checks. Potentially solved by creating composite key definitions.
// Ex: Local.HasKey(e => new { e.LocalCode, e.ActiveFlag };
if (!this.ModelState.IsValid)
{
throw new FilteredException($"Unable to save {typeof(TEntity).Name}. Please make sure all required fields are filled in.");
}
model.AuditUser = this.AuditUser;
TEntity entity;
if (model.IsNewRecord)
{
entity = Activator.CreateInstance<TEntity>();
Mapper.Map(model, entity);
this.Context.Set<TEntity>().Add(entity);
}
else
{
entity = await this.Context.Set<TEntity>().FindAsync(model.GetId());
Mapper.Map(model, entity);
this.Context.Set<TEntity>().Update(entity);
}
await this.Context.SaveChangesAsync();
return entity.GetIdValue();
}
[Route("delete")]
[HttpDelete]
public virtual async Task Delete(int id)
{
var entity = await this.Context.Set<TEntity>().FindAsync(id);
this.Context.Set<TEntity>().Remove(entity);
await this.Context.SaveChangesAsync();
}
}
// With Search
[Route("api/[controller]")]
public abstract class BaseController<TEntity, TModel, TSearchModel> : Controller
where TEntity : BaseEntity
where TModel : BaseModel
where TSearchModel : IPredicateBuilder<TEntity>
{
protected readonly string AuditUser;
protected readonly DbContext Context;
protected BaseController(DbContext context, IHttpContextAccessor accessor)
{
this.Context = context;
this.AuditUser = accessor.HttpContext.User.Identity.Name;
}
[Route("get")]
[HttpGet]
public virtual async Task<TModel> Get(int id)
{
var result = await this.Context.Set<TEntity>().FindAsync(id);
return Mapper.Map<TModel>(result);
}
[Route("list")]
[HttpGet]
public virtual async Task<IEnumerable<TModel>> List()
{
return await this.Context.Set<TEntity>().ProjectTo<TModel>().ToListAsync();
}
[Route("search")]
[HttpPost]
public virtual async Task<IEnumerable<TModel>> Search([FromBody] TSearchModel model)
{
List<TModel> results = await this.Context.Set<TEntity>()
.Where(model.BuildPredicate())
.Take(1000)
.ProjectTo<TModel>()
.ToListAsync();
return results;
}
[Route("createupdate")]
[HttpPost]
public virtual async Task<int> CreateUpdate([FromBody] TModel model)
{
// ToDo: Handle duplicate checks. Potentially solved by creating composite key definitions.
// Ex: Local.HasKey(e => new { e.FirstKey, e.SecondKey };
if (!this.ModelState.IsValid)
{
throw new FilteredException($"Unable to save {typeof(TEntity).Name}. Please make sure all required fields are filled in.");
}
model.AuditUser = this.AuditUser;
TEntity entity;
if (model.IsNewRecord)
{
entity = Activator.CreateInstance<TEntity>();
Mapper.Map(model, entity);
this.Context.Set<TEntity>().Add(entity);
}
else
{
entity = await this.Context.Set<TEntity>().FindAsync(model.GetId());
Mapper.Map(model, entity);
this.Context.Set<TEntity>().Update(entity);
}
await this.Context.SaveChangesAsync();
return entity.GetIdValue();
}
[Route("delete")]
[HttpDelete]
public virtual async Task Delete(int id)
{
var entity = await this.Context.Set<TEntity>().FindAsync(id);
this.Context.Set<TEntity>().Remove(entity);
await this.Context.SaveChangesAsync();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment