Skip to main content
AndanDo is built with modern .NET technologies and carefully selected third-party packages. This page provides a comprehensive overview of the tech stack.

Core Framework

.NET 10.0

Latest LTS version with performance improvements and C# 13 features

Blazor Server

Interactive web UI framework with server-side rendering

ASP.NET Core

Web application framework with middleware pipeline

C# 13

Modern C# with nullable reference types and implicit usings

Project Configuration

The project targets .NET 10.0 with specific compiler features enabled:
AndanDo.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <BlazorDisableThrowNavigationException>true</BlazorDisableThrowNavigationException>
  </PropertyGroup>
</Project>
Key Settings:
  • Nullable: Enabled for null-safety at compile time
  • ImplicitUsings: Common namespaces auto-imported
  • BlazorDisableThrowNavigationException: Prevents exceptions during navigation cancellation

NuGet Packages

AndanDo uses a minimal, focused set of dependencies:

Database & Data Access

Purpose: SQL Server database connectivityUsage: Direct ADO.NET access for high-performance database operations
Services/Auth/AuthService.cs
await using var connection = new SqlConnection(_connectionString);
await connection.OpenAsync(cancellationToken);

await using var command = new SqlCommand("sp_Tours_GetAll", connection)
{
    CommandType = CommandType.StoredProcedure
};

await using var reader = await command.ExecuteReaderAsync(cancellationToken);
Why not Entity Framework?
  • Lower overhead for stored procedure calls
  • More control over query execution
  • Better performance for high-throughput scenarios

Authentication & Security

Purpose: JWT token generation and validationUsage: Creating and validating JSON Web Tokens for authentication
Services/JWT/JwtTokenService.cs
public string GenerateToken(UserIdentity user)
{
    var tokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.UTF8.GetBytes(_jwtOptions.SecretKey);
    
    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(new[]
        {
            new Claim(ClaimTypes.NameIdentifier, user.UserId.ToString()),
            new Claim(ClaimTypes.Email, user.Email)
        }),
        Expires = DateTime.UtcNow.AddMinutes(_jwtOptions.ExpirationMinutes),
        Issuer = _jwtOptions.Issuer,
        Audience = _jwtOptions.Audience,
        SigningCredentials = new SigningCredentials(
            new SymmetricSecurityKey(key),
            SecurityAlgorithms.HmacSha256Signature)
    };
    
    var token = tokenHandler.CreateToken(tokenDescriptor);
    return tokenHandler.WriteToken(token);
}
Features Used:
  • JwtSecurityTokenHandler for token creation
  • HMAC SHA256 signing algorithm
  • Claims-based identity
  • Configurable expiration

Email Services

Purpose: SMTP email sendingUsage: Sending transactional emails (booking confirmations, password resets)
Services/Email/EmailService.cs
public async Task SendEmailAsync(string to, string subject, string htmlBody)
{
    using var client = new SmtpClient();
    
    await client.ConnectAsync(
        _smtpOptions.Host, 
        _smtpOptions.Port, 
        _smtpOptions.UseStartTls ? SecureSocketOptions.StartTls : SecureSocketOptions.None);
    
    if (!string.IsNullOrEmpty(_smtpOptions.User))
    {
        await client.AuthenticateAsync(_smtpOptions.User, _smtpOptions.Password);
    }
    
    var message = new MimeMessage();
    message.From.Add(new MailboxAddress(_smtpOptions.FromName, _smtpOptions.FromEmail));
    message.To.Add(MailboxAddress.Parse(to));
    message.Subject = subject;
    message.Body = new TextPart(TextFormat.Html) { Text = htmlBody };
    
    await client.SendAsync(message);
    await client.DisconnectAsync(true);
}
Why MailKit?
  • Modern, async SMTP client
  • Better than legacy System.Net.Mail.SmtpClient
  • Supports HTML emails with attachments
  • Strong TLS/SSL support

Image Processing

Purpose: Image manipulation and thumbnail generationUsage: Resizing uploaded tour images, creating placeholders
Components/Shared/ImageHelper.cs
public static string GetImageUrlOrPlaceholder(string? imageUrl)
{
    if (string.IsNullOrWhiteSpace(imageUrl))
    {
        return "assets/img/placeholder-tour.jpg";
    }
    
    return imageUrl.StartsWith("http") 
        ? imageUrl 
        : $"/uploads/{imageUrl}";
}
Use Cases:
  • Tour image uploads to wwwroot/uploads/
  • Profile picture processing
  • Image validation and format conversion

Frontend Technologies

While Blazor Server uses C# for UI logic, AndanDo includes JavaScript libraries for enhanced functionality:

JavaScript Libraries

Chart.js (3.7.1)

Dashboard analytics and booking reports visualization

Google Maps API

Tour location mapping and geolocation features

MapLibre GL (3.6.1)

Alternative mapping library for offline/self-hosted maps

Bootstrap 5

CSS framework for responsive design

JavaScript Integration

Components/App.razor
<head>
    <!-- Chart.js for analytics -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script>
    <script src="js/chart-helper.js"></script>
    
    <!-- Google Maps API -->
    <script src="https://maps.googleapis.com/maps/api/js?key=..."></script>
    <script src="https://unpkg.com/@googlemaps/markerclusterer/dist/index.min.js"></script>
    
    <!-- MapLibre GL -->
    <script src="https://unpkg.com/[email protected]/dist/maplibre-gl.js"></script>
    <script src="js/tour-map.js"></script>
    
    <!-- Custom scripts -->
    <script src="assets/js/vendors.js"></script>
    <script src="assets/js/main.js"></script>
</head>
Blazor Server supports JavaScript interop via IJSRuntime for calling JavaScript functions from C# and vice versa.

Data Transfer Objects (DTOs)

AndanDo uses strongly-typed DTOs for data transfer between layers:

DTO Organization

Dtos/
AuthDtos.cs              // LoginRequest, RegisterRequest, AuthResult
TourDtos.cs              // TourDto, TourDetailDto, TourReservationDto
SearchFilterDto.cs       // SearchFilterDto for filtering
PostLikeDtos.cs          // PostLikeDto for likes
FormularioTipoDto.cs     // FormularioTipoDto for form types
SlideDTO.cs              // SlideDTO for image sliders
CoreSettingsDtos.cs      // Application settings DTOs
AppUpdateDtos.cs         // App update notification DTOs

Example DTO Structure

Dtos/AuthDtos.cs
public record LoginRequest(
    string Email,
    string Password
);

public record RegisterRequest(
    string Email,
    string Password,
    string Nombre,
    string? Apellido,
    string? Telefono,
    string? Pais,
    string? Ciudad,
    string? FotoPerfilUrl
);

public record AuthResult(
    int UserId,
    string Email,
    string Token,
    string Nombre,
    string? Apellido,
    string? Telefono,
    string? FotoPerfilUrl
);

public record UserProfileDto(
    int UsuarioId,
    string Email,
    string? Nombre,
    string? Apellido,
    string? Telefono,
    string? Pais,
    string? Ciudad,
    string? FotoPerfilUrl,
    bool EstaActivo,
    bool EstaBloqueado,
    DateTime? FechaCreacion,
    DateTime? FechaActualizacion,
    DateTime? UltimoLogin
);
Using C# records for DTOs provides:
  • Immutability by default
  • Value-based equality
  • Concise syntax with positional parameters
  • Automatic deconstruction

Database Technology

SQL Server

AndanDo uses Microsoft SQL Server for data persistence:

Stored Procedures

Complex business logic encapsulated in database

Parameterized Queries

Protection against SQL injection attacks

Transaction Support

ACID compliance for booking operations

Connection Pooling

Efficient connection reuse with SqlConnection

Connection String Configuration

appsettings.json
{
  "ConnectionStrings": {
    "DefaultConnection": "Server=68.178.201.124;Database=AndandoDB;User Id=csuser;Password=123456*;TrustServerCertificate=true;"
  }
}
Security Reminder: The connection string in the repository contains example credentials. Always replace with secure credentials and use environment variables or Azure Key Vault in production.

External APIs

AndanDo integrates with multiple third-party services:

Payment Gateway

Version: v2Endpoints Used:
  • /v2/checkout/orders - Create payment orders
  • /v2/checkout/orders/{id}/capture - Capture payments
Configuration:
appsettings.json
"PayPal": {
  "Mode": "sandbox",
  "ClientId": "...",
  "ClientSecret": "...",
  "BaseUrl": "https://api-m.sandbox.paypal.com"
}
Implementation: Services/Paypal/PaypalService.cs using HttpClient factory

Geolocation Services

Purpose: Address autocomplete and geocodingFeatures:
  • Search with accent normalization
  • Coordinate-based reverse geocoding
  • No API key required (free tier)
Usage: Search filters with Base64-encoded query parameters
Purpose: Interactive tour location mapsAPI Key Required: Yes (configured in App.razor)Features:
  • Marker clustering for multiple tours
  • Custom map styles
  • Geocoding and Places API

Currency & Localization

Service: CurrencyConversionServicePurpose: Real-time exchange rates for international usersImplementation: HttpClient-based service with caching

Development Tools

Required Tools

.NET SDK 10.0

Download from microsoft.com/net/download

Visual Studio 2024

IDE with Blazor debugging support (optional)

SQL Server

Express edition or Azure SQL Database

Git

Version control system

Compatible Editors

  • Visual Studio 2024: Full debugging, IntelliSense, hot reload
  • Visual Studio Code: With C# extension, lighter weight
  • JetBrains Rider: Excellent Blazor support

Deployment Technologies

IIS

Windows Server hosting with ASP.NET Core Module

Azure App Service

Managed platform with auto-scaling

Docker

Containerized deployment with Dockerfile

Kestrel

Cross-platform web server (built-in)
See the Deployment Guide for detailed instructions on deploying to various platforms.

Browser Compatibility

Blazor Server requires modern browser features:

Supported Browsers

  • Chrome/Edge: 90+ (recommended)
  • Firefox: 88+
  • Safari: 14+
  • Mobile browsers: iOS Safari 14+, Chrome Android 90+

Required Features

  • WebSockets or Server-Sent Events: For SignalR connection
  • JavaScript enabled: Required for Blazor runtime
  • LocalStorage: For ProtectedLocalStorage
  • Fetch API: For HttpClient operations
Internet Explorer is not supported. Blazor Server requires modern web standards that IE does not support.

Performance Characteristics

Package Size Impact

  • Framework-dependent: ~50-100 MB (excluding .NET runtime)
  • Self-contained: ~200-300 MB (includes .NET runtime)
  • Client download: Minimal (~1-2 MB for initial Blazor runtime)
Optimization:
  • Trimming enabled for production builds
  • Static asset compression (gzip/brotli)
  • Minimal external dependencies

Runtime Performance

Server Memory

~30-50 MB per active SignalR connection

Database Queries

Less than 100ms for most stored procedures

Page Load

~500ms initial load, under 200ms navigation

SignalR Latency

~50-150ms for UI updates (WebSocket)

Technology Decisions

Why Blazor Server?

C# everywhere: No context switching between C# and JavaScriptSmall client footprint: UI logic runs on serverSecure: Business logic never exposed to clientFast time-to-interactive: Minimal JavaScript downloadFull .NET ecosystem: Access to all .NET libraries
⚠️ Server resources: Each user consumes server memory⚠️ Latency: UI updates require round-trip to server⚠️ Scaling: Requires sticky sessions for load balancing⚠️ Offline: Cannot work without server connection

Why ADO.NET over Entity Framework?

  • Performance: Direct control over query execution
  • Stored procedures: Better encapsulation of complex business logic
  • Flexibility: Easier to optimize hot paths
  • Learning: Understanding raw SQL improves database skills
Trade-off: More boilerplate code, manual mapping

Why MailKit?

  • Modern API: Async/await throughout
  • Standards compliance: RFC-compliant MIME, SMTP, IMAP
  • Active maintenance: Regular updates and security patches
  • Feature-rich: HTML emails, attachments, embedded images
  • Deprecated alternative: System.Net.Mail.SmtpClient is obsolete

Version Upgrade Path

AndanDo targets .NET 10.0 which is in preview/RC as of March 2026. If you encounter issues:
  1. Downgrade to .NET 8.0 LTS:
    <TargetFramework>net8.0</TargetFramework>
    
  2. Check package compatibility: Most packages support .NET 8.0
  3. Update when stable: Upgrade to .NET 10.0 when it reaches LTS

Next Steps

Project Structure

Explore the file and folder organization

Architecture

Understand the system design

Setup Guide

Set up your development environment

Package Updates

Learn how to update NuGet packages

Build docs developers (and LLMs) love