---
title: "ASP 3.0 to .NET Core Migration - Cargo Tracking System"
slug: "asp-to-dotnet-migration"
summary: "Tech Lead in gradual migration of mission-critical ASP 3.0 system to .NET Core, with dual-write data synchronization and cost reduction of $20k/year in mapping APIs."
client: "Logistics and Tracking Company"
industry: "Logistics & Security"
timeline: "12 months (complete migration)"
role: "Tech Lead & Solution Architect"
image: ""
tags:
  - ASP Classic
  - .NET Core
  - SQL Server
  - Migration
  - Tech Lead
  - OSRM
  - APIs
  - Architecture
featured: true
order: 2
date: 2015-06-01
seo_title: "ASP 3.0 to .NET Core Migration - Carneiro Tech Case Study"
seo_description: "Case study of gradual ASP 3.0 to .NET Core migration with data synchronization and $20k/year cost savings in API expenses."
seo_keywords: "ASP migration, .NET Core, legacy modernization, SQL Server, OSRM, tech lead, routing API"
---

## Overview

Mission-critical cargo monitoring system for high-value loads (LED TVs worth $600 each, shipments up to 1000 units) using GPS satellite tracking. The application covered the entire lifecycle: from driver registration and evaluation (police background checks) to real-time monitoring and final delivery.

**Main challenge:** Migrate legacy ASP 3.0 application to .NET Core with zero downtime, maintaining 24/7 critical operations.

---

## Challenge

### Critical Legacy System

The company operated a mission-critical system in **ASP 3.0** (Classic ASP) that couldn't stop:

**Legacy technology:**
- ASP 3.0 (1998 technology)
- SQL Server 2005
- On-premises failover cluster (perfectly capable of handling the load)
- Integration with GPS satellite trackers
- Google Maps API (cost: **$20,000/year** just for route calculation)

**Constraints:**
- 24/7 system operation with high-value cargo
- No downtime allowed during migration
- Multiple interdependent modules
- Team needed to continue developing features during migration

---

## Solution Architecture

### Phase 1: Infrastructure Preparation (Months 1-3)

#### Database Upgrade
```
SQL Server 2005 → SQL Server 2014
- Full backup and validation
- Stored procedure migration
- Index optimization
- Performance testing
```

#### Dual-Write Synchronization Strategy

I implemented a **bidirectional synchronization system** that allowed:

1. **New modules (.NET Core)** wrote to the new database
2. **Automatic trigger** synchronized data to the legacy database
3. **Old modules (ASP 3.0)** continued working normally
4. **Zero downtime** throughout the entire migration

```csharp
// Synchronization implementation example
public class DualWriteService
{
    public async Task SaveDriver(Driver driver)
    {
        // Write to new database (.NET Core)
        await _newDbContext.Drivers.AddAsync(driver);
        await _newDbContext.SaveChangesAsync();

        // SQL trigger automatically syncs to legacy database
        // ASP 3.0 modules continue functioning
    }
}
```

**Why this approach?**
- Enabled **module-by-module** migration
- Team could continue developing
- Simple rollback if needed
- Reduced operational risk

---

### Phase 2: Gradual Module Migration (Months 4-12)

I migrated modules in increasing complexity order:

**Migration sequence:**
1. ✅ Basic registrations (drivers, vehicles)
2. ✅ Risk assessment (police database integration)
3. ✅ Cargo and route management
4. ✅ Real-time GPS monitoring
5. ✅ Alerts and notifications
6. ✅ Reports and analytics

**Migrated application stack:**
- `.NET Core 1.0` (2015-2016 was the beginning of .NET Core)
- `Entity Framework Core`
- `SignalR` for real-time monitoring
- `SQL Server 2014`
- RESTful APIs

---

### Phase 3: Cost Reduction with OSRM ($20k/year Savings)

#### Problem: Prohibitive Google Maps Cost

The company spent **$20,000/year** just on Google Maps Directions API for truck route calculation.

#### Solution: OSRM (Open Source Routing Machine)

I implemented a solution based on **OSRM** (open-source routing engine):

**Solution architecture:**

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

**Implementation:**

1. **OSRM Server configured** on own server
2. **User-friendly API wrapper** in .NET Core that:
   - Received origin/destination
   - Queried OSRM (free)
   - Returned all route points
   - Formatted for frontend
3. **Frontend** drew the route on Google Maps (visualization only, no routing API)

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

    // Return formatted points for frontend
    return Ok(new {
        points = osrmResponse.Routes[0].Geometry.Coordinates,
        distance = osrmResponse.Routes[0].Distance,
        duration = osrmResponse.Routes[0].Duration
    });
}
```

**Frontend with Leaflet:**

```javascript
// Draw route on map (Google Maps only for tiles)
L.polyline(routePoints, {color: 'red'}).addTo(map);
```

#### OpenStreetMap Attempt

I tried to also replace Google Maps (tiles) with **OpenStreetMap**, which worked technically, but:

❌ **Users didn't like** the appearance
❌ Preferred the familiar Google Maps interface

✅ **Decision:** Keep Google Maps for visualization only (no routing API cost)

**Result:** Savings of **~$20,000/year** while maintaining route quality.

---

## Results & Impact

### Complete Migration in 12 Months

✅ **100% of modules** migrated from ASP 3.0 to .NET Core
✅ **Zero downtime** throughout the entire migration
✅ **Productive team** throughout the process
✅ Faster and more scalable system

### Cost Reduction

💰 **$20,000/year saved** by replacing Google Maps Directions API
📉 **Optimized infrastructure** with SQL Server 2014

### Technical Improvements

🚀 **Performance:** .NET Core application 3x faster than ASP 3.0
🔒 **Security:** Modern stack with active security patches
🛠️ **Maintainability:** Modern C# code vs legacy VBScript
📊 **Monitoring:** SignalR for more efficient real-time tracking

---

## Unexecuted Phase: Microservices & Cloud

### Initial Planning

I participated in the **design and conception** of the second phase (never executed):

**Planned architecture:**
- Migration to **Azure** (cloud was just starting in 2015)
- Break into **microservices**:
  - Authentication service
  - GPS/tracking service
  - Routing service
  - Notification service
- **Event-driven architecture** with message queues

**Why it wasn't executed:**

I left the company right after completing the .NET Core migration. The second phase was planned but not implemented by me.

---

## 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`

---

## Key Decisions & Trade-offs

### Why dual-write synchronization?

**Alternatives considered:**
1. ❌ Big Bang migration (too risky)
2. ❌ Keep everything in ASP 3.0 (unsustainable)
3. ✅ **Gradual migration with sync** (chosen)

**Rationale:**
- Critical system couldn't stop
- Enabled module-by-module rollback
- Team remained productive

### Why OSRM instead of others?

**Alternatives:**
- Google Maps: $20k/year ❌
- Mapbox: Paid license ❌
- GraphHopper: Complex setup ❌
- **OSRM: Open-source, fast, configurable** ✅

### Why not OpenStreetMap for tiles?

**UX-based decision:**
- Technically worked perfectly
- Users preferred familiar Google interface
- **Compromise:** Google Maps for visualization (free) + OSRM for routing (free)

---

## Lessons Learned

### 1. Gradual Migration > Big Bang

Migrating module by module with synchronization enabled:
- Continuous learning
- Route adjustments during the process
- Team and stakeholder confidence

### 2. Open Source Can Save a Lot

OSRM saved **$20k/year** without quality loss. But requires:
- Expertise to configure
- Own infrastructure
- Continuous maintenance

### 3. UX > Technology Sometimes

OpenStreetMap was technically superior (free), but users preferred Google Maps. **Lesson:** Listen to end users.

### 4. Plan for Cloud, but Validate ROI

In 2015, cloud was just starting. On-premises infrastructure (SQL Server cluster) was perfectly capable. **Don't force cloud if there's no clear benefit.**

---

## Context: Why 2015 Was a Special Moment?

**State of technology in 2015:**

- ☁️ **Cloud in early stages:** AWS existed, Azure growing, but low corporate adoption
- 🆕 **.NET Core 1.0 launched** in June 2016 (we used RC during the project)
- 📱 **Microservices:** New concept, Docker in early adoption
- 🗺️ **Google Maps dominant:** Paid APIs, few mature open-source alternatives

**Challenges of the time:**
- Non-existent ASP→.NET migration tools
- Scarce .NET Core documentation (version 1.0!)
- Architecture patterns still consolidating

This project was **pioneering** in adopting .NET Core right at the beginning, when most were migrating to .NET Framework 4.x.

---

**Result:** Successful migration of 24/7 critical system, $20k/year savings, and solid foundation for future evolution.

[Want to discuss a similar migration? Get in touch](#contact)
