using System.Linq; using CleanArchitecture.Application.Common.Exceptions; using CleanArchitecture.Application.Common.Interfaces; using CleanArchitecture.Domain.Entities; using MediatR; using System.Threading; using System.Threading.Tasks; using CleanArchitecture.WebUI.Controllers; using FluentValidation; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace CleanArchitecture.Application.TodoLists.Commands.UpdateTodoList { [Authorize] public class UpdateTodoListController : ApiControllerBase { [HttpPut("{id}")] public async Task<ActionResult> Update(int id, UpdateTodoListCommand command) { if (id != command.Id) { return BadRequest(); } await Mediator.Send(command); return NoContent(); } } public class UpdateTodoListCommand : IRequest { public int Id { get; set; } public string Title { get; set; } } public class UpdateTodoListCommandValidator : AbstractValidator<UpdateTodoListCommand> { private readonly IApplicationDbContext _context; public UpdateTodoListCommandValidator(IApplicationDbContext context) { _context = context; RuleFor(v => v.Title) .NotEmpty().WithMessage("Title is required.") .MaximumLength(200).WithMessage("Title must not exceed 200 characters.") .MustAsync(BeUniqueTitle).WithMessage("The specified title already exists."); } public async Task<bool> BeUniqueTitle(UpdateTodoListCommand model, string title, CancellationToken cancellationToken) { return await _context.TodoLists .Where(l => l.Id != model.Id) .AllAsync(l => l.Title != title); } } public class UpdateTodoListCommandHandler : IRequestHandler<UpdateTodoListCommand> { private readonly IApplicationDbContext _context; public UpdateTodoListCommandHandler(IApplicationDbContext context) { _context = context; } public async Task<Unit> Handle(UpdateTodoListCommand request, CancellationToken cancellationToken) { var entity = await _context.TodoLists.FindAsync(request.Id); if (entity == null) { throw new NotFoundException(nameof(TodoList), request.Id); } entity.Title = request.Title; await _context.SaveChangesAsync(cancellationToken); return Unit.Value; } } }