From 7445a62de30e4f777ef1c0bb30ab132209ad6d48 Mon Sep 17 00:00:00 2001 From: Sharada Shehan Date: Fri, 20 Sep 2024 15:48:17 +0530 Subject: [PATCH] fluent validation changes --- .../Controllers/AdminControllers.cs | 8 ++- .../Controllers/ClerkControllers.cs | 52 ++++++++++++++----- .../Controllers/ImgUploadControllers.cs | 21 +++++--- .../Controllers/StudentControllers.cs | 10 ++-- .../Controllers/TechnicianControllers.cs | 11 ++-- IMS.Presentation/Program.cs | 14 +++-- .../Validators/CreateItemValidator.cs | 1 - .../Validators/CreateLabValidator.cs | 4 +- .../Validators/RespondReservationValidator.cs | 2 +- .../Validators/SubmitMaintenanceValidator.cs | 8 +-- .../Validators/UpdateLabValidator.cs | 6 +-- 11 files changed, 95 insertions(+), 42 deletions(-) diff --git a/IMS.Presentation/Controllers/AdminControllers.cs b/IMS.Presentation/Controllers/AdminControllers.cs index 8fd4026..0267069 100644 --- a/IMS.Presentation/Controllers/AdminControllers.cs +++ b/IMS.Presentation/Controllers/AdminControllers.cs @@ -17,6 +17,7 @@ public class AdminController : ControllerBase private readonly ITokenParser _tokenParser; private readonly ILogger _logger; private readonly IValidator _updateLabDTOValidator; + private readonly IValidator _createLabDTOValidator; private readonly UserService _userService; private readonly LabService _labService; @@ -24,6 +25,7 @@ public AdminController( DataBaseContext dbContext, ILogger logger, IValidator updateLabDTOValidator, + IValidator createLabDTOValidator, ITokenParser tokenParser, UserService userService, LabService labService @@ -32,6 +34,7 @@ LabService labService _dbContext = dbContext; _logger = logger; _updateLabDTOValidator = updateLabDTOValidator; + _createLabDTOValidator = createLabDTOValidator; _tokenParser = tokenParser; _userService = userService; _labService = labService; @@ -78,8 +81,9 @@ public async Task> CreateLab(CreateLabDTO createLabDTO) try { // Validate the DTO - if (!ModelState.IsValid) - BadRequest(ModelState); + var result = await _createLabDTOValidator.ValidateAsync(createLabDTO); + if (!result.IsValid) + return BadRequest(result.Errors); // Create the Lab ResponseDTO responseDTO = _labService.CreateNewLab(createLabDTO); if (!responseDTO.success) diff --git a/IMS.Presentation/Controllers/ClerkControllers.cs b/IMS.Presentation/Controllers/ClerkControllers.cs index da5449d..006e779 100644 --- a/IMS.Presentation/Controllers/ClerkControllers.cs +++ b/IMS.Presentation/Controllers/ClerkControllers.cs @@ -1,4 +1,4 @@ -using System.Diagnostics; +using FluentValidation; using IMS.Application.DTO; using IMS.Application.Services; using IMS.Presentation.Filters; @@ -14,6 +14,12 @@ public class ClerkController : ControllerBase private readonly ITokenParser _tokenParser; private readonly IQRTokenProvider _qRTokenProvider; private readonly ILogger _logger; + private readonly IValidator _createEquipmentValidator; + private readonly IValidator _updateEquipmentValidator; + private readonly IValidator _createItemValidator; + private readonly IValidator _createMaintenanceValidator; + private readonly IValidator _reviewMaintenanceValidator; + private readonly IValidator _respondReservationValidator; private readonly EquipmentService _equipmentService; private readonly ItemService _itemService; private readonly MaintenanceService _maintenanceService; @@ -23,6 +29,12 @@ public ClerkController( ITokenParser tokenParser, IQRTokenProvider qRTokenProvider, ILogger logger, + IValidator createEquipmentValidator, + IValidator updateEquipmentValidator, + IValidator createItemValidator, + IValidator createMaintenanceValidator, + IValidator reviewMaintenanceValidator, + IValidator respondReservationValidator, EquipmentService equipmentService, ItemService itemService, MaintenanceService maintenanceService, @@ -32,6 +44,12 @@ ReservationService reservationService _tokenParser = tokenParser; _qRTokenProvider = qRTokenProvider; _logger = logger; + _createEquipmentValidator = createEquipmentValidator; + _updateEquipmentValidator = updateEquipmentValidator; + _createItemValidator = createItemValidator; + _createMaintenanceValidator = createMaintenanceValidator; + _reviewMaintenanceValidator = reviewMaintenanceValidator; + _respondReservationValidator = respondReservationValidator; _equipmentService = equipmentService; _itemService = itemService; _maintenanceService = maintenanceService; @@ -47,8 +65,9 @@ CreateEquipmentDTO createEquipmentDTO try { // Validate the DTO - if (!ModelState.IsValid) - return BadRequest(ModelState); + var result = await _createEquipmentValidator.ValidateAsync(createEquipmentDTO); + if (!result.IsValid) + return BadRequest(result.Errors); // Create the Equipment ResponseDTO responseDTO = _equipmentService.CreateNewEquipment(createEquipmentDTO); @@ -72,8 +91,9 @@ UpdateEquipmentDTO updateEquipmentDTO try { // Validate the DTO - if (!ModelState.IsValid) - return BadRequest(ModelState); + var result = await _updateEquipmentValidator.ValidateAsync(updateEquipmentDTO); + if (!result.IsValid) + return BadRequest(result.Errors); // Update the Equipment ResponseDTO responseDTO = _equipmentService.UpdateEquipment( id, @@ -116,8 +136,9 @@ public async Task> CreateItem(CreateItemDTO create try { // Validate the DTO - if (!ModelState.IsValid) - return BadRequest(ModelState); + var result = await _createItemValidator.ValidateAsync(createItemDTO); + if (!result.IsValid) + return BadRequest(result.Errors); // Create the Item ResponseDTO responseDTO = _itemService.CreateNewItem( createItemDTO @@ -159,8 +180,9 @@ CreateMaintenanceDTO createMaintenanceDTO try { // Validate the DTO - if (!ModelState.IsValid) - return BadRequest(ModelState); + var result = await _createMaintenanceValidator.ValidateAsync(createMaintenanceDTO); + if (!result.IsValid) + return BadRequest(result.Errors); // Get the User from the token UserDTO? clerkDto = await _tokenParser.getUser( HttpContext.Request.Headers["Authorization"].FirstOrDefault() @@ -190,8 +212,9 @@ ReviewMaintenanceDTO reviewMaintenanceDTO try { // Validate the DTO - if (!ModelState.IsValid) - return BadRequest(ModelState); + var result = await _reviewMaintenanceValidator.ValidateAsync(reviewMaintenanceDTO); + if (!result.IsValid) + return BadRequest(result.Errors); // Get the User from the token UserDTO? clerkDto = await _tokenParser.getUser( HttpContext.Request.Headers["Authorization"].FirstOrDefault() @@ -273,8 +296,11 @@ RespondReservationDTO respondReservationDTO try { // Validate the DTO - if (!ModelState.IsValid) - return BadRequest(ModelState); + var result = await _respondReservationValidator.ValidateAsync( + respondReservationDTO + ); + if (!result.IsValid) + return BadRequest(result.Errors); // Get the User from the token UserDTO? clerkDto = await _tokenParser.getUser( HttpContext.Request.Headers["Authorization"].FirstOrDefault() diff --git a/IMS.Presentation/Controllers/ImgUploadControllers.cs b/IMS.Presentation/Controllers/ImgUploadControllers.cs index 44711d3..a8e3508 100644 --- a/IMS.Presentation/Controllers/ImgUploadControllers.cs +++ b/IMS.Presentation/Controllers/ImgUploadControllers.cs @@ -1,4 +1,4 @@ -using System.Text.Json; +using FluentValidation; using IMS.Application.DTO; using IMS.Infrastructure.Services; using IMS.Presentation.Filters; @@ -12,14 +12,17 @@ public class ImgUploadControllers : ControllerBase { private readonly IBlobStorageClient _blobStorageClient; private readonly ILogger _logger; + private readonly IValidator _presignedUrlRequestValidator; public ImgUploadControllers( IBlobStorageClient blobStorageClient, - ILogger logger + ILogger logger, + IValidator presignedUrlRequestValidator ) { _blobStorageClient = blobStorageClient; _logger = logger; + _presignedUrlRequestValidator = presignedUrlRequestValidator; } [HttpPost("lab")] @@ -31,8 +34,11 @@ PresignedUrlRequestDTO presignedUrlRequestDTO try { // Validate the DTO - if (!ModelState.IsValid) - return BadRequest(ModelState); + var result = await _presignedUrlRequestValidator.ValidateAsync( + presignedUrlRequestDTO + ); + if (!result.IsValid) + return BadRequest(result.Errors); // Generate the presigned URL string blobName = "labs/" @@ -61,8 +67,11 @@ PresignedUrlRequestDTO presignedUrlRequestDTO try { // Validate the DTO - if (!ModelState.IsValid) - return BadRequest(ModelState); + var result = await _presignedUrlRequestValidator.ValidateAsync( + presignedUrlRequestDTO + ); + if (!result.IsValid) + return BadRequest(result.Errors); // Generate the presigned URL string blobName = "equipments/" diff --git a/IMS.Presentation/Controllers/StudentControllers.cs b/IMS.Presentation/Controllers/StudentControllers.cs index 98346e5..d6c539e 100644 --- a/IMS.Presentation/Controllers/StudentControllers.cs +++ b/IMS.Presentation/Controllers/StudentControllers.cs @@ -1,4 +1,4 @@ -using System.Diagnostics; +using FluentValidation; using IMS.Application.DTO; using IMS.Application.Services; using IMS.Presentation.Filters; @@ -14,6 +14,7 @@ public class StudentController : ControllerBase private readonly ITokenParser _tokenParser; private readonly IQRTokenProvider _qRTokenProvider; private readonly ILogger _logger; + private readonly IValidator _requestEquipmentValidator; private readonly ReservationService _reservationService; private readonly UserService _userService; @@ -21,6 +22,7 @@ public StudentController( ITokenParser tokenParser, IQRTokenProvider qRTokenProvider, ILogger logger, + IValidator requestEquipmentValidator, ReservationService reservationService, UserService userService ) @@ -28,6 +30,7 @@ UserService userService _tokenParser = tokenParser; _qRTokenProvider = qRTokenProvider; _logger = logger; + _requestEquipmentValidator = requestEquipmentValidator; _reservationService = reservationService; _userService = userService; } @@ -41,8 +44,9 @@ RequestEquipmentDTO requestEquipmentDTO try { // Validate the DTO - if (!ModelState.IsValid) - return BadRequest(ModelState); + var result = await _requestEquipmentValidator.ValidateAsync(requestEquipmentDTO); + if (!result.IsValid) + return BadRequest(result.Errors); // Get the User from auth token UserDTO? studentDto = await _tokenParser.getUser( HttpContext.Request.Headers["Authorization"].FirstOrDefault() diff --git a/IMS.Presentation/Controllers/TechnicianControllers.cs b/IMS.Presentation/Controllers/TechnicianControllers.cs index 2b8ee69..a8a1b51 100644 --- a/IMS.Presentation/Controllers/TechnicianControllers.cs +++ b/IMS.Presentation/Controllers/TechnicianControllers.cs @@ -1,4 +1,5 @@ -using IMS.Application.DTO; +using FluentValidation; +using IMS.Application.DTO; using IMS.Application.Services; using IMS.Presentation.Filters; using IMS.Presentation.Services; @@ -12,16 +13,19 @@ public class TechnicianController : ControllerBase { private readonly ITokenParser _tokenParser; private readonly ILogger _logger; + private readonly IValidator _submitMaintenanceValidator; private readonly MaintenanceService _maintenanceService; public TechnicianController( ITokenParser tokenParser, ILogger logger, + IValidator submitMaintenanceValidator, MaintenanceService maintenanceService ) { _tokenParser = tokenParser; _logger = logger; + _submitMaintenanceValidator = submitMaintenanceValidator; _maintenanceService = maintenanceService; } @@ -86,8 +90,9 @@ SubmitMaintenanceDTO submitMaintenanceDTO try { // Validate the DTO - if (!ModelState.IsValid) - return BadRequest(ModelState); + var result = await _submitMaintenanceValidator.ValidateAsync(submitMaintenanceDTO); + if (!result.IsValid) + return BadRequest(result.Errors); // Get the User from auth token UserDTO? technicianDto = await _tokenParser.getUser( HttpContext.Request.Headers["Authorization"].FirstOrDefault() diff --git a/IMS.Presentation/Program.cs b/IMS.Presentation/Program.cs index e645fac..62af7f8 100644 --- a/IMS.Presentation/Program.cs +++ b/IMS.Presentation/Program.cs @@ -1,5 +1,4 @@ using FluentValidation; -using FluentValidation.AspNetCore; using IMS.Application.DTO; using IMS.Application.Interfaces; using IMS.Application.Services; @@ -32,9 +31,16 @@ builder.Services.AddControllers(); -builder.Services.AddFluentValidationAutoValidation(); -builder.Services.AddFluentValidationClientsideAdapters(); -builder.Services.AddValidatorsFromAssemblyContaining(); +builder.Services.AddScoped, CreateEquipmentValidator>(); +builder.Services.AddScoped, CreateItemValidator>(); +builder.Services.AddScoped, CreateLabValidator>(); +builder.Services.AddScoped, CreateMaintenanceValidator>(); +builder.Services.AddScoped, PreSignedUrlGenValidator>(); +builder.Services.AddScoped, RequestEquipmentValidator>(); +builder.Services.AddScoped, RespondReservationValidator>(); +builder.Services.AddScoped, ReviewMaintenanceValidator>(); +builder.Services.AddScoped, SubmitMaintenanceValidator>(); +builder.Services.AddScoped, UpdateEquipmentValidator>(); builder.Services.AddScoped, UpdateLabValidator>(); builder.Services.AddEndpointsApiExplorer(); diff --git a/IMS.Presentation/Validators/CreateItemValidator.cs b/IMS.Presentation/Validators/CreateItemValidator.cs index 930db15..c9cfdb8 100644 --- a/IMS.Presentation/Validators/CreateItemValidator.cs +++ b/IMS.Presentation/Validators/CreateItemValidator.cs @@ -6,7 +6,6 @@ namespace IMS.Presentation.Validators public class CreateItemValidator : AbstractValidator { private readonly string textPattern = @"^.{2,20}$"; - private readonly string imageUrlPattern = @"^https?:\/\/.*\.(?:png|jpg|jpeg|webp)$"; public CreateItemValidator() { diff --git a/IMS.Presentation/Validators/CreateLabValidator.cs b/IMS.Presentation/Validators/CreateLabValidator.cs index 177b825..8d00200 100644 --- a/IMS.Presentation/Validators/CreateLabValidator.cs +++ b/IMS.Presentation/Validators/CreateLabValidator.cs @@ -1,6 +1,6 @@ -using FluentValidation; +using System.Text.RegularExpressions; +using FluentValidation; using IMS.Application.DTO; -using System.Text.RegularExpressions; namespace IMS.Presentation.Validators { diff --git a/IMS.Presentation/Validators/RespondReservationValidator.cs b/IMS.Presentation/Validators/RespondReservationValidator.cs index da4e0e5..b83ea98 100644 --- a/IMS.Presentation/Validators/RespondReservationValidator.cs +++ b/IMS.Presentation/Validators/RespondReservationValidator.cs @@ -10,7 +10,7 @@ public RespondReservationValidator() RuleFor(x => x.accepted).NotNull().WithMessage("Accepted status is required."); When( - x => !x.accepted, + x => !(x.accepted), () => { RuleFor(x => x.rejectNote) diff --git a/IMS.Presentation/Validators/SubmitMaintenanceValidator.cs b/IMS.Presentation/Validators/SubmitMaintenanceValidator.cs index d1f41c3..448171c 100644 --- a/IMS.Presentation/Validators/SubmitMaintenanceValidator.cs +++ b/IMS.Presentation/Validators/SubmitMaintenanceValidator.cs @@ -1,5 +1,6 @@ using FluentValidation; using IMS.Application.DTO; +using System.Text.RegularExpressions; namespace IMS.Presentation.Validators { @@ -11,16 +12,15 @@ public SubmitMaintenanceValidator() { // Validate submitNote (optional) RuleFor(x => x.submitNote) - .Cascade(CascadeMode.Stop) - .Matches(notePattern) + .Must(x => x == null || Regex.IsMatch(x, notePattern)) .WithMessage("Invalid Submit Note. Must be between 1 and 100 characters.") - .When(x => !string.IsNullOrEmpty(x.submitNote)); + .When(x => x != null); // Validate cost (optional) RuleFor(x => x.cost) .GreaterThan(0) .WithMessage("Invalid Cost Value. Cost must be a positive integer.") - .When(x => x.cost.HasValue); + .When(x => x != null); } } } diff --git a/IMS.Presentation/Validators/UpdateLabValidator.cs b/IMS.Presentation/Validators/UpdateLabValidator.cs index 35d01e2..02f36aa 100644 --- a/IMS.Presentation/Validators/UpdateLabValidator.cs +++ b/IMS.Presentation/Validators/UpdateLabValidator.cs @@ -13,19 +13,19 @@ public UpdateLabValidator() { // Validate labName RuleFor(x => x.labName) - .Must(x => (x == null) || Regex.IsMatch(x, textPattern)) + .Must(x => x == null || Regex.IsMatch(x, textPattern)) .WithMessage("Invalid Lab Name. Must be between 2 and 20 characters.") .When(x => x != null); // Validate labCode RuleFor(x => x.labCode) - .Must(x => (x == null) || Regex.IsMatch(x, textPattern)) + .Must(x => x == null || Regex.IsMatch(x, textPattern)) .WithMessage("Invalid Lab Code. Must be between 2 and 20 characters.") .When(x => x != null); // Validate imageURL (optional) RuleFor(x => x.imageURL) - .Must(x => (x == null) || Regex.IsMatch(x, imageUrlPattern)) + .Must(x => x == null || Regex.IsMatch(x, imageUrlPattern)) .WithMessage( "Invalid Image URL. Must be a valid URL ending with png, jpg, jpeg, or webp." )