dotnet backend api csharp entity-framework
Configuración Backend con .NET: Guía Completa
Aprende a configurar un backend robusto con .NET Core, incluyendo APIs RESTful, Entity Framework y mejores prácticas de seguridad.
Por Jesus Velez
Configuración Backend con .NET: Guía Completa
En este tutorial, te guiaré a través de la configuración completa de un backend con .NET Core, desde la instalación hasta la implementación de APIs RESTful con Entity Framework.
Prerrequisitos
Antes de comenzar, asegúrate de tener instalado:
- .NET 8 SDK o superior
- Visual Studio Code o Visual Studio
- SQL Server o PostgreSQL
- Postman para pruebas de API
1. Creación del Proyecto
Inicializar el Proyecto Web API
# Crear nuevo proyecto Web API
dotnet new webapi -n MyBackendAPI
cd MyBackendAPI
# Agregar paquetes necesarios
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package Swashbuckle.AspNetCore
2. Configuración de Entity Framework
Modelo de Datos
Creamos nuestro primer modelo:
// Models/User.cs
using System.ComponentModel.DataAnnotations;
namespace MyBackendAPI.Models
{
public class User
{
public int Id { get; set; }
[Required]
[StringLength(100)]
public string Name { get; set; } = string.Empty;
[Required]
[EmailAddress]
public string Email { get; set; } = string.Empty;
[Required]
public string Password { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public bool IsActive { get; set; } = true;
}
}
DbContext Configuration
// Data/ApplicationDbContext.cs
using Microsoft.EntityFrameworkCore;
using MyBackendAPI.Models;
namespace MyBackendAPI.Data
{
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Configuraciones adicionales
modelBuilder.Entity<User>()
.HasIndex(u => u.Email)
.IsUnique();
modelBuilder.Entity<User>()
.Property(u => u.CreatedAt)
.HasDefaultValueSql("GETUTCDATE()");
}
}
}
3. Configuración de Servicios
Program.cs Configuration
// Program.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using MyBackendAPI.Data;
using MyBackendAPI.Services;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Database Configuration
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
// CORS Configuration
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowSpecificOrigins", policy =>
{
policy.WithOrigins("http://localhost:3000", "https://yourdomain.com")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
// JWT Configuration
var jwtSettings = builder.Configuration.GetSection("JwtSettings");
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtSettings["Issuer"],
ValidAudience = jwtSettings["Audience"],
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(jwtSettings["SecretKey"]))
};
});
// Custom Services
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<IAuthService, AuthService>();
var app = builder.Build();
// Configure the HTTP request pipeline
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseCors("AllowSpecificOrigins");
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
4. Implementación de Controladores
UserController
// Controllers/UsersController.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using MyBackendAPI.Models;
using MyBackendAPI.Services;
using MyBackendAPI.DTOs;
namespace MyBackendAPI.Controllers
{
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class UsersController : ControllerBase
{
private readonly IUserService _userService;
public UsersController(IUserService userService)
{
_userService = userService;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<UserDto>>> GetUsers()
{
var users = await _userService.GetAllUsersAsync();
return Ok(users);
}
[HttpGet("{id}")]
public async Task<ActionResult<UserDto>> GetUser(int id)
{
var user = await _userService.GetUserByIdAsync(id);
if (user == null)
return NotFound();
return Ok(user);
}
[HttpPost]
public async Task<ActionResult<UserDto>> CreateUser(CreateUserDto createUserDto)
{
try
{
var user = await _userService.CreateUserAsync(createUserDto);
return CreatedAtAction(nameof(GetUser), new { id = user.Id }, user);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpPut("{id}")]
public async Task<IActionResult> UpdateUser(int id, UpdateUserDto updateUserDto)
{
try
{
await _userService.UpdateUserAsync(id, updateUserDto);
return NoContent();
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteUser(int id)
{
await _userService.DeleteUserAsync(id);
return NoContent();
}
}
}
5. Configuración de Base de Datos
appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=MyBackendDB;Trusted_Connection=true;MultipleActiveResultSets=true;TrustServerCertificate=true"
},
"JwtSettings": {
"SecretKey": "your-super-secret-key-here-should-be-at-least-256-bits",
"Issuer": "MyBackendAPI",
"Audience": "MyBackendAPI-Users",
"ExpiryMinutes": 60
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
6. Migrations y Database Setup
# Crear migration inicial
dotnet ef migrations add InitialCreate
# Actualizar la base de datos
dotnet ef database update
# Ejecutar la aplicación
dotnet run
7. Testing con Postman
Ejemplo de Endpoints
# GET Users
GET https://localhost:7000/api/users
Authorization: Bearer {your-jwt-token}
# POST Create User
POST https://localhost:7000/api/users
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com",
"password": "SecurePassword123"
}
8. Mejores Prácticas de Seguridad
Validación de Entrada
// DTOs/CreateUserDto.cs
using System.ComponentModel.DataAnnotations;
namespace MyBackendAPI.DTOs
{
public class CreateUserDto
{
[Required(ErrorMessage = "El nombre es requerido")]
[StringLength(100, MinimumLength = 2, ErrorMessage = "El nombre debe tener entre 2 y 100 caracteres")]
public string Name { get; set; } = string.Empty;
[Required(ErrorMessage = "El email es requerido")]
[EmailAddress(ErrorMessage = "El formato del email no es válido")]
public string Email { get; set; } = string.Empty;
[Required(ErrorMessage = "La contraseña es requerida")]
[StringLength(100, MinimumLength = 8, ErrorMessage = "La contraseña debe tener al menos 8 caracteres")]
[RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]",
ErrorMessage = "La contraseña debe contener al menos una mayúscula, una minúscula, un número y un carácter especial")]
public string Password { get; set; } = string.Empty;
}
}
9. Logging y Monitoreo
Configuración de Logging
// Program.cs - Logging configuration
builder.Logging.ClearProviders();
builder.Logging.AddConsole();
builder.Logging.AddFile("Logs/app-{Date}.log");
Conclusión
Con esta configuración, tienes una base sólida para un backend .NET que incluye:
- ✅ API RESTful completa
- ✅ Autenticación JWT
- ✅ Entity Framework con SQL Server
- ✅ Validación de datos
- ✅ Configuración de CORS
- ✅ Logging estructurado
- ✅ Documentación Swagger
Próximos Pasos
- Implementar refresh tokens
- Agregar paginación a los endpoints
- Implementar caching con Redis
- Configurar CI/CD con GitHub Actions
- Agregar tests unitarios y de integración
¿Te resultó útil este tutorial? ¡Déjame saber en los comentarios si tienes alguna pregunta!