---
title: "Migración ASP 3.0 a .NET Core - Sistema de Rastreo de Cargas"
slug: "asp-to-dotnet-migration"
summary: "Tech Lead en la migración gradual de sistema crítico ASP 3.0 a .NET Core, con sincronización de datos entre versiones y reducción de costos de $20k/año en APIs de mapeo."
client: "Empresa de Logística y Rastreo"
industry: "Logística & Seguridad"
timeline: "12 meses (migración completa)"
role: "Tech Lead & Solution Architect"
image: ""
tags:
  - ASP Classic
  - .NET Core
  - SQL Server
  - Migration
  - Tech Lead
  - OSRM
  - APIs
  - Arquitectura
featured: true
order: 2
date: 2015-06-01
seo_title: "Migración ASP 3.0 a .NET Core - Case Carneiro Tech"
seo_description: "Caso de migración gradual de aplicación ASP 3.0 a .NET Core con sincronización de datos y reducción de $20k/año en costos de APIs."
seo_keywords: "ASP migration, .NET Core, legacy modernization, SQL Server, OSRM, tech lead, routing API"
---

## Descripción General

Sistema crítico de monitoreo de cargas de alto valor (TVs LED de $600 cada una, cargamentos de hasta 1000 unidades) utilizando rastreo GPS vía satélite. La aplicación cubría todo el ciclo: desde registro y evaluación de conductores (verificación de antecedentes policiales) hasta monitoreo en tiempo real y entrega final.

**Desafío principal:** Migrar aplicación legacy ASP 3.0 a .NET Core sin downtime, manteniendo operación crítica 24/7.

---

## Desafío

### Sistema Legacy Crítico

La empresa operaba un sistema mission-critical en **ASP 3.0** (Classic ASP) que no podía detenerse:

**Tecnología legacy:**
- ASP 3.0 (tecnología de 1998)
- SQL Server 2005
- Cluster failover on-premises (perfectamente capaz de soportar la carga)
- Integración con rastreadores GPS vía satélite
- Google Maps API (costo: **$20,000/año** solo para cálculo de rutas)

**Restricciones:**
- Sistema operando 24/7 con cargas de alto valor
- Imposibilidad de downtime durante migración
- Múltiples módulos interdependientes
- Equipo necesitaba continuar desarrollando features durante la migración

---

## Arquitectura de Solución

### Fase 1: Preparación de Infraestructura (Meses 1-3)

#### Upgrade de Base de Datos
```
SQL Server 2005 → SQL Server 2014
- Backup completo y validación
- Migración de stored procedures
- Optimización de índices
- Pruebas de performance
```

#### Estrategia de Sincronización Dual-Write

Implementé un **sistema de sincronización bidireccional** que permitía:

1. **Módulos nuevos (.NET Core)** escribían en la base de datos nueva
2. **Trigger automático** sincronizaba datos hacia la base de datos legacy
3. **Módulos antiguos (ASP 3.0)** continuaban funcionando normalmente
4. **Zero downtime** durante toda la migración

```csharp
// Ejemplo de sincronización implementada
public class DualWriteService
{
    public async Task SaveDriver(Driver driver)
    {
        // Escribe en base de datos nueva (.NET Core)
        await _newDbContext.Drivers.AddAsync(driver);
        await _newDbContext.SaveChangesAsync();

        // Trigger SQL sincroniza automáticamente hacia base de datos legacy
        // Módulos ASP 3.0 continúan funcionando
    }
}
```

**¿Por qué este enfoque?**
- Permitió migración **módulo por módulo**
- Equipo podía continuar desarrollando
- Rollback sencillo si fuera necesario
- Reducción de riesgo operacional

---

### Fase 2: Migración Gradual de Módulos (Meses 4-12)

Migré los módulos en orden de complejidad creciente:

**Orden de migración:**
1. ✅ Registros básicos (conductores, vehículos)
2. ✅ Evaluación de riesgo (integración con base policial)
3. ✅ Gestión de cargas y rutas
4. ✅ Monitoreo GPS en tiempo real
5. ✅ Alertas y notificaciones
6. ✅ Reportes y analytics

**Stack de la aplicación migrada:**
- `.NET Core 1.0` (2015-2016 era el inicio de .NET Core)
- `Entity Framework Core`
- `SignalR` para monitoreo real-time
- `SQL Server 2014`
- APIs RESTful

---

### Fase 3: Reducción de Costos con OSRM (Ahorro de $20k/año)

#### Problema: Costo Prohibitivo de Google Maps

La empresa gastaba **$20,000/año** solo en Google Maps Directions API para cálculo de rutas de camiones.

#### Solución: OSRM (Open Source Routing Machine)

Implementé una solución basada en **OSRM** (motor de ruteo open-source):

**Arquitectura de la solución:**

```
┌─────────────────┐
│  Frontend       │
│  (Leaflet.js)   │
└────────┬────────┘
         │
         ▼
┌─────────────────┐      ┌──────────────┐
│  API Wrapper    │─────▶│  OSRM Server │
│  (.NET Core)    │      │  (self-hosted)│
└────────┬────────┘      └──────────────┘
         │
         ▼
┌─────────────────┐
│  Google Maps    │
│  (display only) │
└─────────────────┘
```

**Implementación:**

1. **Servidor OSRM configurado** en servidor propio
2. **API wrapper amigable** en .NET Core que:
   - Recibía origen/destino
   - Consultaba OSRM (gratuito)
   - Devolvía todos los puntos de la ruta
   - Formateaba para el frontend
3. **Frontend** dibujaba la ruta en Google Maps (solo visualización, sin API de rutas)

```csharp
[HttpGet("route")]
public async Task<IActionResult> GetRoute(double originLat, double originLng,
                                           double destLat, double destLng)
{
    // Consulta OSRM (gratuito)
    var osrmResponse = await _osrmClient.GetRouteAsync(
        originLat, originLng, destLat, destLng);

    // Retorna puntos formateados para el frontend
    return Ok(new {
        points = osrmResponse.Routes[0].Geometry.Coordinates,
        distance = osrmResponse.Routes[0].Distance,
        duration = osrmResponse.Routes[0].Duration
    });
}
```

**Frontend con Leaflet:**

```javascript
// Dibuja ruta en el mapa (Google Maps solo para tiles)
L.polyline(routePoints, {color: 'red'}).addTo(map);
```

#### Intento con OpenStreetMap

Intenté sustituir también Google Maps (tiles) por **OpenStreetMap**, que funcionó técnicamente, pero:

❌ **A los usuarios no les gustó** la apariencia
❌ Preferían la interfaz familiar de Google Maps

✅ **Decisión:** Mantener Google Maps solo para visualización (sin costo de API de rutas)

**Resultado:** Ahorro de **~$20,000/año** manteniendo calidad de las rutas.

---

## Resultados e Impacto

### Migración Completa en 12 Meses

✅ **100% de los módulos** migrados de ASP 3.0 a .NET Core
✅ **Zero downtime** durante toda la migración
✅ **Equipo productivo** durante todo el proceso
✅ Sistema más rápido y escalable

### Reducción de Costos

💰 **$20,000/año ahorrados** con sustitución de Google Maps Directions API
📉 **Infraestructura optimizada** con SQL Server 2014

### Mejoras Técnicas

🚀 **Performance:** Aplicación .NET Core 3x más rápida que ASP 3.0
🔒 **Seguridad:** Stack moderno con parches de seguridad activos
🛠️ **Mantenibilidad:** Código C# moderno vs VBScript legacy
📊 **Monitoreo:** SignalR para tracking real-time más eficiente

---

## Fase No Ejecutada: Microservicios & Cloud

### Planificación Inicial

Participé en el **diseño y concepción** de la segunda fase (nunca ejecutada):

**Arquitectura planificada:**
- Migración a **Azure** (cloud estaba apenas comenzando en 2015)
- División en **microservicios**:
  - Servicio de autenticación
  - Servicio de GPS/tracking
  - Servicio de rutas
  - Servicio de notificaciones
- **Event-driven architecture** con message queues

**Por qué no fue ejecutada:**

Salí de la empresa inmediatamente después de concluir la migración a .NET Core. La segunda fase quedó planificada pero no fue implementada por mí.

---

## Tech Stack

`ASP 3.0` `VBScript` `.NET Core 1.0` `C#` `Entity Framework Core` `SQL Server 2005` `SQL Server 2014` `OSRM` `Leaflet.js` `Google Maps` `SignalR` `REST APIs` `GPS/Satellite` `Migration Strategy` `Dual-Write Pattern`

---

## Decisiones Clave & Trade-offs

### ¿Por qué sincronización dual-write?

**Alternativas consideradas:**
1. ❌ Big Bang migration (demasiado arriesgado)
2. ❌ Mantener todo en ASP 3.0 (insostenible)
3. ✅ **Migración gradual con sync** (elegido)

**Justificación:**
- Sistema crítico no podía detenerse
- Permitió rollback módulo por módulo
- Equipo continuó productivo

### ¿Por qué OSRM en vez de otros?

**Alternativas:**
- Google Maps: $20k/año ❌
- Mapbox: Licencia paga ❌
- GraphHopper: Configuración compleja ❌
- **OSRM: Open-source, rápido, configurable** ✅

### ¿Por qué no OpenStreetMap para tiles?

**Decisión basada en UX:**
- Técnicamente funcionó perfectamente
- Usuarios preferían interfaz familiar de Google
- **Compromiso:** Google Maps para visualización (gratis) + OSRM para rutas (gratis)

---

## Lecciones Aprendidas

### 1. Migración Gradual > Big Bang

Migrar módulo por módulo con sincronización permitió:
- Aprendizaje continuo
- Ajustes de ruta durante el proceso
- Confianza del equipo y stakeholders

### 2. Open Source Puede Ahorrar Mucho

OSRM ahorró **$20k/año** sin pérdida de calidad. Pero requiere:
- Expertise para configurar
- Infraestructura propia
- Mantenimiento continuo

### 3. UX > Tecnología A Veces

OpenStreetMap era técnicamente superior (gratuito), pero usuarios prefirieron Google Maps. **Lección:** Escuchar a los usuarios finales.

### 4. Planifique Cloud, pero Valide el ROI

En 2015, cloud estaba comenzando. La infraestructura on-premises (cluster SQL Server) era perfectamente capaz. **No fuerce cloud si no hay beneficio claro.**

---

## Contexto: Por qué 2015 fue un Momento Especial

**Estado de la tecnología en 2015:**

- ☁️ **Cloud en pañales:** AWS existía, Azure creciendo, pero adopción corporativa aún baja
- 🆕 **.NET Core 1.0 lanzado** en junio/2016 (usamos RC durante proyecto)
- 📱 **Microservicios:** Concepto nuevo, Docker en adopción inicial
- 🗺️ **Google Maps dominante:** APIs pagas, pocas alternativas open-source maduras

**Desafíos de la época:**
- Herramientas de migración ASP→.NET inexistentes
- Documentación .NET Core escasa (versión 1.0!)
- Patrones de arquitectura aún consolidándose

Este proyecto fue **pionero** al adoptar .NET Core al inicio, cuando la mayoría migraba a .NET Framework 4.x.

---

**Resultado:** Migración exitosa de sistema crítico 24/7, ahorro de $20k/año, y base sólida para evolución futura.

[¿Quiere discutir una migración similar? Póngase en contacto](#contact)
