WebApiToolkit Description
A set of useful C# reusable classes and components that could be used with any Net Core Web application, contains:
-
Dto clasess:
-
OperationResultDtorepresents result of operation that changes Data in db -
PagedDataDtorepresents portion (page) of same objects (any type)
-
-
Controllers classes - abstract classes
- basic read controller (
BasicReadController) contains 2 methods:- GET /api/[controller]/?page={page}&size={size} to get PagedDataDto
- GET /api/[controller]/{id} to get one object by id
- full CRUD controller (
BasicCrudController) = basic read controller (BasicReadController) + Create, Update and Delete operations :- POST /api/[controller] - for new object creation
- PUT /api/[controller]/{id} - for object with id edit
- DELETE /api/[controller]/{id} - for object with id delete
Controllers classes expects that all operation will be performed using Manager classes (each controller must have it own manager)
- basic read controller (
-
Managers classes - classes that implements business logic of application
-
IModelManager- interface that describes basic operations -
ModelManageris abstract class that contains impl of Get operations
-
Requirements
There is only ONE requirement: all Entity classes that are using with controllers & managers derived from this library base classes MUST work
with Entities that IMPLEMENTS interface IModelIdentifiable<T> from Wissance.WebApiToolkit.Data.Entity
Nuget
NUGET PACKAGE: https://www.nuget.org/packages/Wissance.WebApiToolkit/1.0.0
Examples
Here we consider only Full CRUD controllers because Full CRUD = Read Only + Additional Operations (CREATE, UPDATE, DELETE), a full example = full application created with Wissance.WebApiToolkit could be found here: https://github.com/Wissance/WeatherControl
[ApiController]
public class StationController : BasicCrudController<StationDto, StationEntity, int>
{
public StationController(StationManager manager)
{
Manager = manager; // this is for basic operations
_manager = manager; // this for extended operations
}
private StationManager _manager;
}
public class StationManager : ModelManager<StationEntity, StationDto, int>
{
public StationManager(ModelContext modelContext, ILoggerFactory loggerFactory) : base(loggerFactory)
{
_modelContext = modelContext;
}
public override async Task<OperationResultDto<IList<StationDto>>> GetAsync(int page, int size)
{
return await GetAsync<int>(_modelContext.Stations, page, size, null, null, StationFactory.Create);
}
public override async Task<OperationResultDto<StationDto>> GetByIdAsync(int id)
{
return await GetAsync(_modelContext.Stations, id, StationFactory.Create);
}
public override async Task<OperationResultDto<StationDto>> CreateAsync(StationDto data)
{
try
{
StationEntity entity = StationFactory.Create(data);
await _modelContext.Stations.AddAsync(entity);
int result = await _modelContext.SaveChangesAsync();
if (result >= 0)
{
return new OperationResultDto<StationDto>(true, (int)HttpStatusCode.Created, null, StationFactory.Create(entity));
}
return new OperationResultDto<StationDto>(false, (int)HttpStatusCode.InternalServerError, "An unknown error occurred during station creation", null);
}
catch (Exception e)
{
return new OperationResultDto<StationDto>(false, (int)HttpStatusCode.InternalServerError, $"An error occurred during station creation: {e.Message}", null);
}
}
public override async Task<OperationResultDto<StationDto>> UpdateAsync(int id, StationDto data)
{
try
{
StationEntity entity = StationFactory.Create(data);
StationEntity existingEntity = await _modelContext.Stations.FirstOrDefaultAsync(s => s.Id == id);
if (existingEntity == null)
{
return new OperationResultDto<StationDto>(false, (int)HttpStatusCode.NotFound, $"Station with id: {id} does not exists", null);
}
// Copy only name, description and positions, create measurements if necessary from MeasurementsManager
existingEntity.Name = entity.Name;
existingEntity.Description = existingEntity.Description;
existingEntity.Latitude = existingEntity.Latitude;
existingEntity.Longitude = existingEntity.Longitude;
int result = await _modelContext.SaveChangesAsync();
if (result >= 0)
{
return new OperationResultDto<StationDto>(true, (int)HttpStatusCode.OK, null, StationFactory.Create(entity));
}
return new OperationResultDto<StationDto>(false, (int)HttpStatusCode.InternalServerError, "An unknown error occurred during station update", null);
}
catch (Exception e)
{
return new OperationResultDto<StationDto>(false, (int)HttpStatusCode.InternalServerError, $"An error occurred during station update: {e.Message}", null);
}
}
public override async Task<OperationResultDto<bool>> DeleteAsync(int id)
{
return await DeleteAsync(_modelContext, _modelContext.Stations, id);
}
private readonly ModelContext _modelContext;
}
JUST 2 VERY SIMPLE CLASSES ^^ USING WebApiToolkit
Create Controllers for full CRUD operations
Full CRUD with additional method, see example below
Using WebApiToolkit we could also:
- extend
controllerandmanagerclasses - use authorization by passing
IHttpContextAccessorto Manager and check somthing like this:ClaimsPrincipal principal = _httpContext.HttpContext.User;