ASP NET


Introducción a ASP.NET Core

ASP.NET Core es un framework multiplataforma, modular y de alto rendimiento para construir aplicaciones web modernas. Permite crear APIs, aplicaciones MVC, Blazor, microservicios y aplicaciones en tiempo real (SignalR).

Ventajas principales:

  • Multiplataforma (Windows, Linux, macOS)
  • Integración nativa con Azure y contenedores Docker
  • Arquitectura modular y de código abierto
  • Alta performance gracias a Kestrel y al runtime optimizado de .NET
  • Seguridad, autenticación y autorización integradas
  • Integración con Entity Framework Core para persistencia de datos

Arquitectura base

ASP.NET Core sigue el patrón Middleware Pipeline, donde cada componente maneja la solicitud HTTP en una secuencia controlada.

Componentes comunes del pipeline:

  • UseRouting(): define las rutas de la aplicación.
  • UseAuthentication() y UseAuthorization(): gestionan seguridad.
  • UseEndpoints(): mapea las rutas a los controladores o handlers.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();
app.Run();

`


ASP.NET Core MVC

Patrón MVC

El patrón Model-View-Controller separa la lógica de negocio, la presentación y el control de flujo.

  • Model: representa los datos y reglas del dominio.
  • View: define la interfaz visual (HTML + Razor).
  • Controller: maneja las solicitudes, coordina modelos y vistas.
public class HomeController : Controller
{
	public IActionResult Index()
	{
		var model = new WelcomeModel { Message = "Hola desde ASP.NET Core MVC" };
		return View(model);
	}
}

Características Clave

  • Soporte de Razor para vistas dinámicas.
  • Enlace de modelos automático (Model Binding).
  • Validación con DataAnnotations.
  • Inyección de dependencias integrada.

ASP.NET Core Web API

Diseñado para crear servicios RESTful con JSON, XML u otros formatos de salida.

Características principales:

  • Atributos como [HttpGet], [HttpPost], [HttpPut], [HttpDelete]
  • Versionado de API nativo
  • Middleware para CORS, Autenticación JWT y Swagger
  • Serialización JSON con System.Text.Json o Newtonsoft.Json
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
	private readonly IProductService _service;

	public ProductsController(IProductService service)
	{
		_service = service;
	}

	[HttpGet]
	public async Task<IEnumerable<Product>> Get() => await _service.GetAllAsync();

	[HttpPost]
	public async Task<IActionResult> Create(Product product)
	{
		await _service.AddAsync(product);
		return CreatedAtAction(nameof(Get), new { id = product.Id }, product);
	}
}

Blazor

Blazor permite construir interfaces web interactivas usando C# en lugar de JavaScript, tanto en el cliente (WebAssembly) como en el servidor.

Modos de ejecución:

  • Blazor Server: Renderizado en el servidor, conexión persistente por SignalR.
  • Blazor WebAssembly: Corre directamente en el navegador.
  • Blazor Hybrid: Integración con aplicaciones de escritorio o móviles (MAUI).

Ventajas:

  • Reutilización de código entre front y back.
  • Integración directa con .NET y sus librerías.
  • Componentes reutilizables y fuerte tipado.
@page "/counter"

<h3>Contador</h3>

<p>Valor actual: @count</p>

<button @onclick="Incrementar">Incrementar</button>

@code {
	int count = 0;
	void Incrementar() => count++;
}

Integración con SQL Server y EF Core

ASP.NET Core se integra con Entity Framework Core para manejar bases de datos relacionales.

Ejemplo de configuración:

builder.Services.AddDbContext<AppDbContext>(options =>
	options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

Migraciones y uso básico:

dotnet ef migrations add InitialCreate
dotnet ef database update

Publicación y despliegue

ASP.NET Core permite desplegar aplicaciones de múltiples formas:

  • Contenedores Docker
  • Servicios cloud (Azure App Service, AWS Elastic Beanstalk)
  • Kubernetes / microservicios
  • Publicación auto-contenida (dotnet publish -r)

Ejemplo:

dotnet publish -c Release -o ./publish

Luego puede subirse a Azure o ejecutarse en un contenedor con:

docker build -t myapp .
docker run -p 5000:80 myapp

Casos prácticos

1. API de gestión de usuarios

Integrando autenticación JWT, controladores REST y Entity Framework.

2. Aplicación administrativa MVC

Dashboard con gráficos y exportación a Excel usando ClosedXML y app para exportar a excel con plantillas angular, net y cell.

3. Sistema Blazor con SignalR

App en tiempo real para notificaciones o chats.


Buenas prácticas

  • Usar inyección de dependencias (AddScoped, AddTransient, AddSingleton)
  • Centralizar configuración en appsettings.json
  • Versionar APIs correctamente
  • Habilitar CORS para clientes externos
  • Implementar logging con ILogger<T>
  • Monitorear con Application Insights o Serilog
  • Optimizar rendimiento con caching y compresión

Recursos adicionales

ASP.NET Core – Avanzado y prácticas profesionales


Middleware y filtros avanzados

Middleware personalizado

Permite interceptar el pipeline HTTP para aplicar lógica global (logging, auditoría, headers, etc.).

public class RequestTimingMiddleware
{
	private readonly RequestDelegate _next;
	public RequestTimingMiddleware(RequestDelegate next) => _next = next;

	public async Task InvokeAsync(HttpContext context)
	{
		var watch = Stopwatch.StartNew();
		await _next(context);
		watch.Stop();

		Console.WriteLine($"[{context.Request.Path}] ejecutado en {watch.ElapsedMilliseconds}ms");
	}
}

`

Registro:

app.UseMiddleware<RequestTimingMiddleware>();

Filtros globales en MVC o API

Los filtros permiten ejecutar lógica antes o después de acciones o controladores.

Tipos:

  • ActionFilter (antes/después de la acción)
  • ResultFilter (antes/después del resultado)
  • ExceptionFilter (manejo centralizado de errores)
  • AuthorizationFilter (control de acceso)
public class GlobalExceptionFilter : IExceptionFilter
{
	public void OnException(ExceptionContext context)
	{
		context.Result = new ObjectResult(new { error = context.Exception.Message })
		{
			StatusCode = 500
		};
	}
}

Registro global:

builder.Services.AddControllers(options =>
{
	options.Filters.Add<GlobalExceptionFilter>();
});

Seguridad y autenticación

ASP.NET Core Identity

Proporciona registro, login y roles de usuario listos para usar. Se puede combinar con EF Core y tokens JWT.

JWT (JSON Web Tokens)

Ideal para APIs REST. El token se firma y se envía en cada petición.

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
	.AddJwtBearer(options =>
	{
		options.TokenValidationParameters = new TokenValidationParameters
		{
			ValidateIssuer = true,
			ValidateAudience = true,
			ValidateLifetime = true,
			ValidateIssuerSigningKey = true,
			IssuerSigningKey = new SymmetricSecurityKey(
				Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
		};
	});

Ejemplo de autorización:

[Authorize(Roles = "Admin")]
[HttpGet("dashboard")]
public IActionResult GetDashboard() => Ok("Bienvenido administrador");

OAuth2 y OpenID Connect

Integración con proveedores como Azure AD, Google, GitHub o Auth0 mediante AddOpenIdConnect() o AddOAuth().


Rendimiento y optimización

Caching

En memoria:

builder.Services.AddMemoryCache();
public class ProductService
{
	private readonly IMemoryCache _cache;
	public ProductService(IMemoryCache cache) => _cache = cache;

	public async Task<IEnumerable<Product>> GetAll()
	{
		if (!_cache.TryGetValue("products", out IEnumerable<Product> products))
		{
			products = await LoadProductsAsync();
			_cache.Set("products", products, TimeSpan.FromMinutes(5));
		}
		return products;
	}
}

Output caching (ASP.NET Core 8+):

app.UseOutputCache();
app.MapGet("/data", () => "cached data").CacheOutput();

Compresión y respuesta optimizada

builder.Services.AddResponseCompression();
app.UseResponseCompression();

Optimización de DI (inyección de dependencias)

  • Evitar Singleton con dependencias que usen DbContext
  • Usar Scoped para servicios transaccionales
  • Evitar dependencias circulares
  • Registrar interfaces, no implementaciones directas

Logging y monitoreo

Logging estructurado con Serilog

builder.Host.UseSerilog((context, config) =>
{
	config.ReadFrom.Configuration(context.Configuration)
		  .Enrich.FromLogContext()
		  .WriteTo.Console()
		  .WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day);
});

Ventajas:

  • Logs estructurados en JSON
  • Enriquecimiento con contexto (usuario, requestId, etc.)
  • Integración con Application Insights, Seq, Elasticsearch

Health checks y monitoreo

builder.Services.AddHealthChecks()
	.AddSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));

app.MapHealthChecks("/health");

Permite que Azure o Kubernetes verifiquen el estado del servicio.


Arquitectura limpia y modular

ASP.NET Core se adapta perfectamente al enfoque de Clean Architecture o Onion Architecture.

Capas recomendadas:

  1. Domain: entidades, lógica pura, interfaces.
  2. Application: casos de uso, CQRS, validaciones.
  3. Infrastructure: acceso a datos, servicios externos.
  4. Presentation: controladores o endpoints de API.

Ejemplo de estructura:

src/
 ├─ Domain/
 ├─ Application/
 │   ├─ Commands/
 │   ├─ Queries/
 ├─ Infrastructure/
 └─ WebApi/

Inyección modular

Cada capa registra sus servicios con un método de extensión:

public static class InfrastructureDI
{
	public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration config)
	{
		services.AddDbContext<AppDbContext>(options =>
			options.UseSqlServer(config.GetConnectionString("Default")));
		return services;
	}
}

Testing y calidad

Unit tests con xUnit o NUnit

public class ProductServiceTests
{
	[Fact]
	public async Task GetAll_ShouldReturnProducts()
	{
		var service = new ProductService(new FakeRepo());
		var result = await service.GetAll();
		Assert.NotEmpty(result);
	}
}

Integration tests con WebApplicationFactory

Permite probar el pipeline HTTP completo:

var app = new WebApplicationFactory<Program>();
var client = app.CreateClient();
var response = await client.GetAsync("/api/products");

Test de performance y carga

Usar herramientas como:

  • k6
  • JMeter
  • Azure Load Testing

Despliegue e integración continua (CI/CD)

CI/CD con GitHub Actions o Azure DevOps

Ejemplo YAML básico para GitHub Actions:

name: Build and Deploy ASP.NET Core

on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup .NET
        uses: actions/setup-dotnet@v3
        with:
          dotnet-version: 8.0.x
      - name: Build
        run: dotnet build --configuration Release
      - name: Publish
        run: dotnet publish -c Release -o ./publish

Despliegue en Azure App Service

az webapp up --runtime "DOTNET:8" --name myapp --resource-group myrg

O usando un contenedor:

docker build -t myapp .
docker run -p 8080:80 myapp

Caso práctico completo

Proyecto: Gestión de pedidos y usuarios (API + Blazor Admin) Características:

  • Clean Architecture + CQRS
  • Entity Framework Core con SQL Server
  • JWT Authentication
  • Serilog + Health Checks
  • Despliegue en Azure App Service

Flujo general:

  1. API REST con OrdersController y UsersController
  2. Autenticación JWT para proteger endpoints
  3. Blazor Admin consume la API
  4. Logging estructurado y health check en /health
  5. CI/CD automatizado con GitHub Actions

Buenas prácticas finales

  • Activar HTTPS obligatorio (UseHttpsRedirection)
  • Aplicar políticas de CORS específicas, no globales
  • Versionar APIs correctamente (v1, v2)
  • Usar CancellationToken en métodos async
  • Validar entrada de usuario siempre (FluentValidation)
  • Configurar entorno (Development, Staging, Production)
  • Monitorear rendimiento y errores con Application Insights

Recursos complementarios