From 30337d1ed7ef32ded2eadef71ecdd3ce8ece177d Mon Sep 17 00:00:00 2001 From: Kevin MONDEJAR Date: Thu, 3 Apr 2025 10:41:34 +0200 Subject: [PATCH 1/3] route character --- WF_EF_Api/Contextlib/DbCharacterManager.cs | 23 +++- WF_EF_Api/Dto2Entities/Extention.cs | 1 + WF_EF_Api/ServicesApi/CharacterService.cs | 8 +- WF_EF_Api/Shared/ICharacterService.cs | 2 + .../WfApi/Controllers/CharacterController.cs | 128 ++++++++++++++++++ 5 files changed, 158 insertions(+), 4 deletions(-) create mode 100644 WF_EF_Api/WfApi/Controllers/CharacterController.cs diff --git a/WF_EF_Api/Contextlib/DbCharacterManager.cs b/WF_EF_Api/Contextlib/DbCharacterManager.cs index 7d01f7f..d7385aa 100644 --- a/WF_EF_Api/Contextlib/DbCharacterManager.cs +++ b/WF_EF_Api/Contextlib/DbCharacterManager.cs @@ -2,6 +2,7 @@ using Microsoft.EntityFrameworkCore; using Shared; using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; @@ -12,12 +13,14 @@ namespace Contextlib public class DbCharacterManager : ICharacterService { private WTFContext _context; - private GenericRepository _repo; + private GenericRepository _repo; + private DbImagesManager _dbI; public DbCharacterManager(WTFContext context) { _context = context ?? throw new ArgumentNullException(nameof(context), "Database context cannot be null."); _repo = new GenericRepository(_context); + _dbI = new DbImagesManager(context); } /// @@ -32,6 +35,12 @@ namespace Contextlib { throw new ArgumentNullException(nameof(character), "character cannot be null."); } + var image = await _dbI.GetImageByPath(character.Images.ImgPath); + if (image != null) + { + character.IdImage = image.Id; + character.Images = image; + } _repo.Insert(character); await _context.SaveChangesAsync(); } @@ -93,6 +102,12 @@ namespace Contextlib return lastCharId; } + public async Task> GetSomeChar(int page, int count) + { + var charLst = _repo.GetItems(page, count, [nameof(Character.Images)]).ToList(); + return new PaginationResult(charLst.Count, 0, charLst.Count, charLst); + } + /// /// Removes a character from the database by its ID. /// @@ -119,9 +134,11 @@ namespace Contextlib if (charac != null) { bool change = false; - if (character.IdImage != 0) + var image = await _dbI.GetImageByPath(character.Images.ImgPath); + if (image != null) { - charac.IdImage = character.IdImage; + charac.IdImage = image.Id; + charac.Images = image; change = true; } if (character.Name != null) diff --git a/WF_EF_Api/Dto2Entities/Extention.cs b/WF_EF_Api/Dto2Entities/Extention.cs index fcd8407..5b28630 100644 --- a/WF_EF_Api/Dto2Entities/Extention.cs +++ b/WF_EF_Api/Dto2Entities/Extention.cs @@ -261,6 +261,7 @@ namespace Dto2Entities Character character = new Character(); character.Id = item.Id; character.Name = item.Name; + character.Images = new Images(); character.Images.ImgPath = item.imagePath ; return character; } diff --git a/WF_EF_Api/ServicesApi/CharacterService.cs b/WF_EF_Api/ServicesApi/CharacterService.cs index 399586a..53daa1e 100644 --- a/WF_EF_Api/ServicesApi/CharacterService.cs +++ b/WF_EF_Api/ServicesApi/CharacterService.cs @@ -33,7 +33,7 @@ namespace ServicesApi public async Task GetCharById(int id) { - return characterService.GetCharById(id).Result.ToDto(); + return (await characterService.GetCharById(id)).ToDto(); } public async Task GetCharByName(string name) @@ -46,6 +46,12 @@ namespace ServicesApi return await characterService.GetLastCharId(); } + public async Task> GetSomeChar(int page, int count) + { + var characters = (await characterService.GetSomeChar(page, count)).items; + return new PaginationResult(characters.Count(), page, count, characters.ToDto()); + } + public async Task RemoveCharacter(int id) { await characterService.RemoveCharacter(id); diff --git a/WF_EF_Api/Shared/ICharacterService.cs b/WF_EF_Api/Shared/ICharacterService.cs index a1c1a57..a4fd18d 100644 --- a/WF_EF_Api/Shared/ICharacterService.cs +++ b/WF_EF_Api/Shared/ICharacterService.cs @@ -35,5 +35,7 @@ namespace Shared // Retrieves the unique identifier of the last added character. Task GetLastCharId(); + + Task> GetSomeChar(int page, int count); } } diff --git a/WF_EF_Api/WfApi/Controllers/CharacterController.cs b/WF_EF_Api/WfApi/Controllers/CharacterController.cs new file mode 100644 index 0000000..4789f1c --- /dev/null +++ b/WF_EF_Api/WfApi/Controllers/CharacterController.cs @@ -0,0 +1,128 @@ +using System.Net; +using DTO; +using Entity; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Shared; + +namespace WfApi.Controllers +{ + [ApiController] + [Route("api/v1/character")] //Version API + public class CharacterController : ControllerBase + { + private readonly ICharacterService _character; + + private readonly ILogger _logger; + + public CharacterController(ICharacterService characterService, ILogger logger) + { + _character = characterService; + _logger = logger; + + } + + [HttpGet("{id}")] // Indiquer que l'id est dans l'URL + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetCharacter(int id) + { + try + { + try + { + var character = await _character.GetCharById(id); + return Ok(character); + } + catch(KeyNotFoundException e) + { + return NotFound(); + } + } + catch (Exception e) + { + return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error (" + e + ")" }); + } + } + + [HttpGet("all")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task GetAllSource(int index = 0, int count = 10) + { + try + { + var result = await _character.GetSomeChar(index, count); + + if (result != null) + { + return await Task.FromResult(Ok(result)); + } + else + { + return NoContent(); + } + } + catch (Exception e) + { + return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error (" + e + ")" }); + } + } + + [HttpPost] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public async Task CreateCharacter([FromBody] CharacterDTO newCharacter) + { + try + { + if (newCharacter == null) + { + return BadRequest(new { message = "Source data is required." }); + } + try + { + var existingSource = await _character.GetCharById(newCharacter.Id); + return Conflict(new { message = "A source with this ID already exists." }); + } + catch (KeyNotFoundException e) + { + await _character.AddCharacter(newCharacter); + return CreatedAtAction(nameof(GetAllSource), new { id = newCharacter.Id }, newCharacter); + } + } + catch (Exception e) + { + return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error (" + e + ")" }); + } + } + + [HttpPut()] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task UpdateCharacter([FromQuery] int id, [FromBody] CharacterDTO updatedCharacter) + { + try + { + if (updatedCharacter == null) + { + return BadRequest(new { message = "new source data is required." }); + } + + var result = _character.UpdateCharacter(id, updatedCharacter); + + return Ok(result); + } + catch (Exception e) + { + return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error (" + e + ")" }); + } + } + } +} From 4d5b895fd8836d3e2865415550045119a9eeb75d Mon Sep 17 00:00:00 2001 From: Kevin MONDEJAR Date: Thu, 3 Apr 2025 11:27:06 +0200 Subject: [PATCH 2/3] ajout controleur image --- WF_EF_Api/Contextlib/DbImagesManager.cs | 7 +- WF_EF_Api/ServicesApi/ImageService.cs | 18 ++- WF_EF_Api/Shared/IImagesService.cs | 2 + .../WfApi/Controllers/ImageController.cs | 141 ++++++++++++++++++ 4 files changed, 166 insertions(+), 2 deletions(-) create mode 100644 WF_EF_Api/WfApi/Controllers/ImageController.cs diff --git a/WF_EF_Api/Contextlib/DbImagesManager.cs b/WF_EF_Api/Contextlib/DbImagesManager.cs index e549cf9..0fcd548 100644 --- a/WF_EF_Api/Contextlib/DbImagesManager.cs +++ b/WF_EF_Api/Contextlib/DbImagesManager.cs @@ -35,7 +35,12 @@ namespace Contextlib public async Task GetImageById(int id) { - return _repository.GetById(id); + var image = _repository.GetById(id); + if(image == null) + { + throw new KeyNotFoundException($"No image with the id {id}"); + } + return image; } public async Task GetLastImageId() diff --git a/WF_EF_Api/ServicesApi/ImageService.cs b/WF_EF_Api/ServicesApi/ImageService.cs index caefb31..0427f0f 100644 --- a/WF_EF_Api/ServicesApi/ImageService.cs +++ b/WF_EF_Api/ServicesApi/ImageService.cs @@ -7,6 +7,7 @@ using DTO; using Entity; using Shared; using Dto2Entities; +using static System.Net.Mime.MediaTypeNames; namespace ServicesApi { @@ -32,7 +33,22 @@ namespace ServicesApi public async Task GetImageById(int id) { - return imageService.GetImageById(id).Result.ToDto(); + var image = await imageService.GetImageById(id); + if (image == null) + { + throw new KeyNotFoundException($"No image with the id {id}"); + } + return image.ToDto(); + } + + public async Task GetImageByPath(string path) + { + var image = await imageService.GetImageByPath(path); + if (image == null) + { + return null; + } + return image.ToDto(); } public async Task GetLastImageId() diff --git a/WF_EF_Api/Shared/IImagesService.cs b/WF_EF_Api/Shared/IImagesService.cs index 0bc6bf0..7cf0cd3 100644 --- a/WF_EF_Api/Shared/IImagesService.cs +++ b/WF_EF_Api/Shared/IImagesService.cs @@ -35,5 +35,7 @@ namespace Shared // Retrieves the last Image ID. Task GetLastImageId(); + + Task GetImageByPath(string path); } } diff --git a/WF_EF_Api/WfApi/Controllers/ImageController.cs b/WF_EF_Api/WfApi/Controllers/ImageController.cs new file mode 100644 index 0000000..1ffd55b --- /dev/null +++ b/WF_EF_Api/WfApi/Controllers/ImageController.cs @@ -0,0 +1,141 @@ +using DTO; +using System.Net; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Shared; +using Entity; + +namespace WfApi.Controllers +{ + [ApiController] + [Route("api/v1/image")] //Version API + public class ImageController : ControllerBase + { + private readonly IImagesService _img; + private readonly ILogger _logger; + + public ImageController(IImagesService imgService, ILogger logger) + { + _img = imgService; + _logger = logger; + } + + + [HttpGet("{id}")] // Indiquer que l'id est dans l'URL + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetImageId(int id) + { + try + { + try + { + var image = await _img.GetImageById(id); + return Ok(image); + } + catch (KeyNotFoundException e) + { + return NotFound(); + } + } + catch (Exception e) + { + return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error (" + e + ")" }); + } + } + + [HttpGet("all")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task GetAllImage(int index = 0, int count = 10) + { + try + { + var result = await _img.GetSomeImage(index, count); + if (result == null) + { + return NotFound(); + } + return Ok(result); + } + catch (KeyNotFoundException e) + { + return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" }); + } + } + + [HttpPost] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public async Task CreateImage([FromBody] ImageDTO newImage) + { + try + { + if(newImage == null) + { + return BadRequest(new { message = "Source data is required." }); + } + try + { + var existImage = await _img.GetImageById(newImage.IdImage); + return Conflict(new { message = $"A Image with the ID {newImage.IdImage} already exists." }); + } + catch(KeyNotFoundException e) + { + var existPath = await _img.GetImageByPath(newImage.ImagePath); + if(existPath == null) + { + await _img.AddImage(newImage); + return Ok(newImage); + } + return Conflict(new { message = $"A Image with the path {newImage.ImagePath} already exists." }); + } + } + catch(Exception e) + { + return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" }); + } + } + + + + [HttpPut()] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task UpdateImage([FromQuery] int id, [FromBody] ImageDTO updatedImage) + { + try + { + if (updatedImage == null) + { + return BadRequest(new { message = "new source data is required." }); + } + try + { + var existImage = await _img.GetImageById(id); + var existPath = await _img.GetImageByPath(updatedImage.ImagePath); + if (existPath == null) + { + await _img.UpdateImage(id, updatedImage); + return Ok(updatedImage); + } + return Conflict(new { message = $"A Image with the path {updatedImage.ImagePath} already exists." }); + } + catch (KeyNotFoundException e) + { + return Conflict(new { message = $"A Image with the ID {id} dosen't exists." }); + } + } + catch (Exception e) + { + return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error (" + e + ")" }); + } + } + + } +} From d952cb6bf05269018985086f9c194cd01a10d521 Mon Sep 17 00:00:00 2001 From: Kevin MONDEJAR Date: Thu, 3 Apr 2025 11:47:48 +0200 Subject: [PATCH 3/3] micro modif controleur --- .../WfApi/Controllers/CharacterController.cs | 45 +++++++++++-------- .../Controllers/CommentariesController.cs | 4 ++ 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/WF_EF_Api/WfApi/Controllers/CharacterController.cs b/WF_EF_Api/WfApi/Controllers/CharacterController.cs index 4789f1c..c1cc18d 100644 --- a/WF_EF_Api/WfApi/Controllers/CharacterController.cs +++ b/WF_EF_Api/WfApi/Controllers/CharacterController.cs @@ -36,14 +36,14 @@ namespace WfApi.Controllers var character = await _character.GetCharById(id); return Ok(character); } - catch(KeyNotFoundException e) + catch(KeyNotFoundException) { return NotFound(); } } - catch (Exception e) + catch (Exception) { - return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error (" + e + ")" }); + return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" }); } } @@ -66,39 +66,39 @@ namespace WfApi.Controllers return NoContent(); } } - catch (Exception e) + catch (Exception) { - return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error (" + e + ")" }); + return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" }); } } [HttpPost] [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task CreateCharacter([FromBody] CharacterDTO newCharacter) { try { if (newCharacter == null) { - return BadRequest(new { message = "Source data is required." }); + return BadRequest(new { message = "Character data is required." }); } try { var existingSource = await _character.GetCharById(newCharacter.Id); - return Conflict(new { message = "A source with this ID already exists." }); + return Conflict(new { message = "A character with this ID already exists." }); } - catch (KeyNotFoundException e) + catch (KeyNotFoundException) { await _character.AddCharacter(newCharacter); - return CreatedAtAction(nameof(GetAllSource), new { id = newCharacter.Id }, newCharacter); + return Ok(newCharacter); } } - catch (Exception e) + catch (Exception) { - return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error (" + e + ")" }); + return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" }); } } @@ -106,22 +106,29 @@ namespace WfApi.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] + [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task UpdateCharacter([FromQuery] int id, [FromBody] CharacterDTO updatedCharacter) { try { if (updatedCharacter == null) { - return BadRequest(new { message = "new source data is required." }); + return BadRequest(new { message = "new character data is required." }); + } + try + { + var existChar = await _character.GetCharById(id); + var result = _character.UpdateCharacter(id, updatedCharacter); + return Ok(result); + } + catch(KeyNotFoundException) + { + return Conflict(new { message = "A character with this ID already exists." }); } - - var result = _character.UpdateCharacter(id, updatedCharacter); - - return Ok(result); } - catch (Exception e) + catch (Exception) { - return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error (" + e + ")" }); + return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" }); } } } diff --git a/WF_EF_Api/WfApi/Controllers/CommentariesController.cs b/WF_EF_Api/WfApi/Controllers/CommentariesController.cs index 7fd26bc..5e25f45 100644 --- a/WF_EF_Api/WfApi/Controllers/CommentariesController.cs +++ b/WF_EF_Api/WfApi/Controllers/CommentariesController.cs @@ -22,6 +22,10 @@ namespace WfApi.Controllers [HttpGet("{id}")] // Indiquer que l'id est dans l'URL + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task GetCommentary(int id, int index = 0, int count = 5) { try