Add the Post Endpoint
In the Models folder add a new file called CreateTaskDto.cs
namespace CrudAppAPI.Models;
public class CreateTaskDto
{
public string Title { get; set; } = default!;
public string? Description { get; set; }
public DateTime? DueDate { get; set; }
public bool Completed { get; set; } = false;
}
Create a new folder called Validators, and a new file called CreateTaskDtoValidator.cs
using CrudAppAPIV2.Models;
using FluentValidation;
namespace CrudAppAPIV2.Validators;
public class CreateTaskDtoValidator: AbstractValidator<CreateTaskDto>
{
public CreateTaskDtoValidator()
{
RuleFor(x => x.Title)
.NotEmpty()
.MaximumLength(100);
RuleFor(x => x.Description)
.MaximumLength(255);
RuleFor(x => x.DueDate)
.GreaterThanOrEqualTo(DateTime.Today)
.When(x => x.DueDate.HasValue);
}
}
Register the following services in the Program.cs file
builder.Services.AddFluentValidationAutoValidation();
builder.Services.AddValidatorsFromAssemblyContaining<CreateTaskDtoValidator>();
In the TaskServices.cs file add a method called AddTaskAsync
public async Task AddTaskAsync(CreateTaskDto dto)
{
using var conn = await _connectionFactory.CreateConnectionAsync();
var parameters = new DynamicParameters();
parameters.Add("@Title", dto.Title);
parameters.Add("@Description", dto.Description);
parameters.Add("@DueDate", dto.DueDate);
parameters.Add("@Completed", dto.Completed);
await conn.ExecuteAsync("AddTask", parameters, commandType: CommandType.StoredProcedure);
}
Add the endpoint to the TaskEndpoints.cs file
app.MapPost("/api/tasks", async (CreateTaskDto dto, TaskService service, IValidator<CreateTaskDto> validator) =>
{
// Validate the DTO using FluentValidation
var validationResult = await validator.ValidateAsync(dto);
if (!validationResult.IsValid)
{
// If validation fails, return a BadRequest with validation errors
return Results.BadRequest(validationResult.Errors);
}
// If validation passes, proceed with adding the task
await service.AddTaskAsync(dto);
// Return a success response
return Results.Ok();
});
You will need to import the Models with a using statement as we use the one we created as a parameter in this method
Example JSON payload
{
"title": "Write blog post",
"description": "Topic: Clean Architecture",
"dueDate": "2025-07-10",
"completed": false
}