From 3c85969f5aa8793000298dbbe41599b1588443a9 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Mon, 1 Jul 2024 16:10:46 +0200 Subject: [PATCH] =?UTF-8?q?Separate=20CRUDControllerBase=20mit=20Fehlerbeh?= =?UTF-8?q?andlung=20hinzugef=C3=BCgt.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.API/CRUDControllerBase.cs | 122 +++++-------- .../CRUDControllerBaseWithErrorHandling.cs | 172 ++++++++++++++++++ 2 files changed, 213 insertions(+), 81 deletions(-) create mode 100644 DigitalData.Core.API/CRUDControllerBaseWithErrorHandling.cs diff --git a/DigitalData.Core.API/CRUDControllerBase.cs b/DigitalData.Core.API/CRUDControllerBase.cs index 1d099c5..f3de4a6 100644 --- a/DigitalData.Core.API/CRUDControllerBase.cs +++ b/DigitalData.Core.API/CRUDControllerBase.cs @@ -46,27 +46,19 @@ namespace DigitalData.Core.API [HttpPost] public virtual async Task Create(TCreateDto createDto) { - try - { - return await _service.CreateAsync(createDto).ThenAsync( - Success: id => - { - var createdResource = new { Id = id }; - var actionName = nameof(GetById); - var routeValues = new { id = createdResource.Id }; - return CreatedAtAction(actionName, routeValues, createdResource); - }, - Fail: (messages, notices) => - { - _logger.LogNotice(notices); - return BadRequest(messages); - }); - } - catch (Exception ex) - { - _logger.LogError(ex, "{Message}", ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError); - } + return await _service.CreateAsync(createDto).ThenAsync( + Success: id => + { + var createdResource = new { Id = id }; + var actionName = nameof(GetById); + var routeValues = new { id = createdResource.Id }; + return CreatedAtAction(actionName, routeValues, createdResource); + }, + Fail: (messages, notices) => + { + _logger.LogNotice(notices); + return BadRequest(messages); + }); } /// @@ -77,21 +69,13 @@ namespace DigitalData.Core.API [HttpGet("{id}")] public virtual async Task GetById([FromRoute] TId id) { - try - { - return await _service.ReadByIdAsync(id).ThenAsync( - Success: Ok, - Fail: IActionResult (messages, notices) => - { - _logger.LogNotice(notices); - return NotFound(messages); - }); - } - catch (Exception ex) - { - _logger.LogError(ex, "{Message}", ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError); - } + return await _service.ReadByIdAsync(id).ThenAsync( + Success: Ok, + Fail: IActionResult (messages, notices) => + { + _logger.LogNotice(notices); + return NotFound(messages); + }); } /// @@ -101,21 +85,13 @@ namespace DigitalData.Core.API [HttpGet] public virtual async Task GetAll() { - try - { - return await _service.ReadAllAsync().ThenAsync( - Success: Ok, - Fail: IActionResult (messages, notices) => - { - _logger.LogNotice(notices); - return NotFound(messages); - }); - } - catch (Exception ex) - { - _logger.LogError(ex, "{Message}", ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError); - } + return await _service.ReadAllAsync().ThenAsync( + Success: Ok, + Fail: IActionResult (messages, notices) => + { + _logger.LogNotice(notices); + return NotFound(messages); + }); } /// @@ -126,21 +102,13 @@ namespace DigitalData.Core.API [HttpPut] public virtual async Task Update(TUpdateDto updateDto) { - try - { - return await _service.UpdateAsync(updateDto).ThenAsync( - Success: Ok, - Fail: IActionResult (messages, notices) => - { - _logger.LogNotice(notices); - return BadRequest(messages); - }); - } - catch(Exception ex) - { - _logger.LogError(ex, "{Message}", ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError); - } + return await _service.UpdateAsync(updateDto).ThenAsync( + Success: Ok, + Fail: IActionResult (messages, notices) => + { + _logger.LogNotice(notices); + return BadRequest(messages); + }); } /// @@ -151,21 +119,13 @@ namespace DigitalData.Core.API [HttpDelete("{id}")] public virtual async Task Delete([FromRoute] TId id) { - try - { - return await _service.DeleteAsyncById(id).ThenAsync( - Success: Ok, - Fail: IActionResult (messages, notices) => - { - _logger.LogNotice(notices); - return BadRequest(messages); - }); - } - catch (Exception ex) - { - _logger.LogError(ex, "{Message}", ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError); - } + return await _service.DeleteAsyncById(id).ThenAsync( + Success: Ok, + Fail: IActionResult (messages, notices) => + { + _logger.LogNotice(notices); + return BadRequest(messages); + }); } } } \ No newline at end of file diff --git a/DigitalData.Core.API/CRUDControllerBaseWithErrorHandling.cs b/DigitalData.Core.API/CRUDControllerBaseWithErrorHandling.cs new file mode 100644 index 0000000..19a499c --- /dev/null +++ b/DigitalData.Core.API/CRUDControllerBaseWithErrorHandling.cs @@ -0,0 +1,172 @@ +using DigitalData.Core.Abstractions.Application; +using DigitalData.Core.DTO; +using Microsoft.AspNetCore.Mvc; + +namespace DigitalData.Core.API +{ + /// + /// A base controller class that provides generic CRUD (Create, Read, Update, Delete) operations for a specified entity type, + /// with enhanced error handling to ensure robust and reliable API endpoints. + /// + /// The derived CRUD service type implementing ICRUDService. + /// The Data Transfer Object type for create operations. + /// The Data Transfer Object type for read operations. + /// The Data Transfer Object type for update operations. + /// The entity type CRUD operations will be performed on. + /// The type of the entity's identifier. + [ApiController] + [Route("api/[controller]")] + public class CRUDControllerBaseWithErrorHandling : ControllerBase + where TCRUDService : ICRUDService + where TCreateDto : class + where TReadDto : class + where TUpdateDto : class + where TEntity : class + { + protected readonly ILogger _logger; + protected readonly TCRUDService _service; + + /// + /// Initializes a new instance of the CRUDControllerBase class with specified logger and CRUD service. + /// + /// The logger to be used by the controller. + /// The CRUD service handling business logic for the entity. + public CRUDControllerBaseWithErrorHandling( + ILogger logger, + TCRUDService service) + { + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _service = service ?? throw new ArgumentNullException(nameof(service)); + } + + /// + /// Creates a new entity based on the provided DTO. + /// + /// The DTO from which to create the entity. + /// A task that represents the asynchronous create operation. The task result contains the action result. + [HttpPost] + public virtual async Task Create(TCreateDto createDto) + { + try + { + return await _service.CreateAsync(createDto).ThenAsync( + Success: id => + { + var createdResource = new { Id = id }; + var actionName = nameof(GetById); + var routeValues = new { id = createdResource.Id }; + return CreatedAtAction(actionName, routeValues, createdResource); + }, + Fail: (messages, notices) => + { + _logger.LogNotice(notices); + return BadRequest(messages); + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "{Message}", ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); + } + } + + /// + /// Retrieves an entity by its identifier. + /// + /// The identifier of the entity to retrieve. + /// A task that represents the asynchronous read operation. The task result contains the action result. + [HttpGet("{id}")] + public virtual async Task GetById([FromRoute] TId id) + { + try + { + return await _service.ReadByIdAsync(id).ThenAsync( + Success: Ok, + Fail: IActionResult (messages, notices) => + { + _logger.LogNotice(notices); + return NotFound(messages); + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "{Message}", ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); + } + } + + /// + /// Retrieves all entities. + /// + /// A task that represents the asynchronous read-all operation. The task result contains the action result. + [HttpGet] + public virtual async Task GetAll() + { + try + { + return await _service.ReadAllAsync().ThenAsync( + Success: Ok, + Fail: IActionResult (messages, notices) => + { + _logger.LogNotice(notices); + return NotFound(messages); + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "{Message}", ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); + } + } + + /// + /// Updates an existing entity based on the provided DTO. + /// + /// The DTO containing the updated data for the entity. + /// A task that represents the asynchronous update operation. The task result contains the action result. + [HttpPut] + public virtual async Task Update(TUpdateDto updateDto) + { + try + { + return await _service.UpdateAsync(updateDto).ThenAsync( + Success: Ok, + Fail: IActionResult (messages, notices) => + { + _logger.LogNotice(notices); + return BadRequest(messages); + }); + } + catch(Exception ex) + { + _logger.LogError(ex, "{Message}", ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); + } + } + + /// + /// Deletes an entity by its identifier. + /// + /// The identifier of the entity to delete. + /// A task that represents the asynchronous delete operation. The task result contains the action result. + [HttpDelete("{id}")] + public virtual async Task Delete([FromRoute] TId id) + { + try + { + return await _service.DeleteAsyncById(id).ThenAsync( + Success: Ok, + Fail: IActionResult (messages, notices) => + { + _logger.LogNotice(notices); + return BadRequest(messages); + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "{Message}", ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); + } + } + } +} \ No newline at end of file