$mermaidjs
Clean Architecture Demo
Loading...
Searching...
No Matches
TasksController.cs
Go to the documentation of this file.
1// TaskManagement.API/Controllers/TasksController.cs
2using MediatR;
3using Microsoft.AspNetCore.Authorization;
4using Microsoft.AspNetCore.Mvc;
5using System.Security.Claims;
9
11
56[ApiController]
57[Route("api/[controller]")]
58public sealed class TasksController : ControllerBase
59{
60 private readonly IMediator _mediator;
61 public TasksController(IMediator mediator)
62 {
63 _mediator = mediator;
64 }
65
66 [HttpGet("{id:guid}")]
67 [ProducesResponseType(typeof(TaskDto), StatusCodes.Status200OK)]
68 [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
69 public async Task<ActionResult<TaskDto>> GetById(
70 Guid id,
71 CancellationToken cancellationToken)
72 {
73 var result = await _mediator.Send(
74 new GetTaskByIdQuery(id),
75 cancellationToken).ConfigureAwait(false);
76
77 if (result.IsSuccess)
78 {
79 return Ok(result.Value);
80 }
81
82 return result.Errors.Any(error => error.Contains("not found", StringComparison.OrdinalIgnoreCase))
83 ? NotFound(CreateProblemDetails(result.Errors))
84 : BadRequest(CreateProblemDetails(result.Errors));
85 }
86
87 [HttpPost]
88 [Authorize]
89 [ProducesResponseType(typeof(Guid), StatusCodes.Status201Created)]
90 [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
91 public async Task<ActionResult<Guid>> Create(
92 [FromBody] CreateTaskRequest request,
93 CancellationToken cancellationToken)
94 {
95 var command = new CreateTaskCommand(
96 request.Title,
97 request.Description,
98 request.Priority,
99 request.DueDate,
100 GetUserId(User)
101 );
102 var result = await _mediator.Send(command, cancellationToken).ConfigureAwait(false);
103
104 if (result.IsSuccess)
105 {
106 return CreatedAtAction(
107 nameof(GetById),
108 new {
109 id = result.Value
110 },
111 result.Value);
112 }
113
114 return BadRequest(CreateValidationProblemDetails(result.Errors));
115 }
116
117 [HttpPost("{id:guid}/complete")]
118 [Authorize]
119 [ProducesResponseType(StatusCodes.Status204NoContent)]
120 [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
121 public async Task<ActionResult> Complete(
122 Guid id,
123 CancellationToken cancellationToken)
124 {
125 var result = await _mediator.Send(
126 new CompleteTaskCommand(id),
127 cancellationToken).ConfigureAwait(false);
128
129 if (result.IsSuccess)
130 {
131 return NoContent();
132 }
133
134 return BadRequest(CreateProblemDetails(result.Errors));
135 }
136
137 private static ProblemDetails CreateProblemDetails(IReadOnlyList<string> errors)
138 {
139 return new ProblemDetails {
140 Title = "Request failed",
141 Detail = string.Join("; ", errors),
142 Status = StatusCodes.Status400BadRequest
143 };
144 }
145
146 private static ValidationProblemDetails CreateValidationProblemDetails(
147 IReadOnlyList<string> errors)
148 {
149 return new ValidationProblemDetails(
150 errors.ToDictionary(
151 _ => "General",
152 e => new[] { e })) {
153 Title = "Validation failed",
154 Status = StatusCodes.Status400BadRequest
155 };
156 }
157
158 private static Guid GetUserId(ClaimsPrincipal user)
159 {
160 // Soportar nombres comunes de reclamación JWT/user-jwts para ID de usuario.
161 var candidateValues = user.Claims
162 .Where(c =>
163 c.Type == ClaimTypes.NameIdentifier ||
164 c.Type == "sub" ||
165 c.Type == "nameid" ||
166 c.Type == "oid" ||
167 c.Type == "uid" ||
168 c.Type == "userId")
169 .Select(c => c.Value);
170
171 foreach (var candidate in candidateValues)
172 {
173 if (Guid.TryParse(candidate, out var parsedUserId))
174 {
175 return parsedUserId;
176 }
177 }
178
179 throw new InvalidOperationException("The current user does not have a valid GUID user id claim.");
180 }
181}
builder.Services. typeof(ValidationBehavior<,>)) .AddDbContext< TaskDbContext >(options
TasksController es el endpoint de la API REST para operaciones de gestión de tareas.
async Task< ActionResult > Complete(Guid id, CancellationToken cancellationToken)
async Task< ActionResult< TaskDto > > GetById(Guid id, CancellationToken cancellationToken)
async Task< ActionResult< Guid > > Create([FromBody] CreateTaskRequest request, CancellationToken cancellationToken)
CompleteTaskCommand encapsula la solicitud de marcar una tarea como completada.
CreateTaskCommand encapsula la solicitud de creación de una nueva tarea.
GetTaskByIdQuery encapsula una solicitud para recuperar una sola tarea por ID.
CreateTaskRequest es el DTO de los datos de entrada de la solicitud HTTP para crear una nueva tarea a...