Blazor .NET Template

.NET Version ASP.NET Core Entity Framework Core MQTTnet Bootstrap License: MIT

A comprehensive .NET template featuring REST API, MQTT support, SQLite database, OpenAPI/Swagger documentation, Blazor Server UI built with ASP.NET Core, and Template scrips.

Blazor .NET Template

πŸ“– Table of Contents

πŸ“š Documentation

Full documentation is available on GitHub Pages:

Features

πŸš€ Core Features

πŸ› οΈ Development

πŸ“¦ Deployment

πŸ”§ Customization

Customizing the Application Name

The template comes with scripts to easily rename the application from β€œblazor-net-app” to your own application name.

Using Bash (Linux/macOS)

./rename-app.sh my-cool-app

Using PowerShell (Windows)

.\Rename-App.ps1 -NewAppName my-cool-app

The scripts will:

Note: The app name should be in kebab-case (lowercase with hyphens, e.g., my-cool-app).

Quick Start

Prerequisites

Quick Setup: Use the provided setup script to install all dependencies automatically:

# Install all dependencies at once (Linux/macOS)
./scripts/setup.sh

Or install dependencies individually:

./scripts/install-dotnet10.sh    # .NET 10 SDK
./scripts/install-sqlite3.sh     # SQLite3
./scripts/install-mosquitto.sh   # MQTT broker
./scripts/install-docker.sh      # Docker and Docker Compose

Running Locally

  1. Clone the repository

    git clone https://github.com/mlmdevs/blazor-net-template.git
    cd blazor-net-template
    
  2. Start with Docker Compose

    Linux/macOS:

    ./docker-dev.sh start
    

    Windows (PowerShell):

    .\docker-dev.ps1 -Command start
    

    This will:

    • Build the Docker image
    • Start the application container
    • Start a Mosquitto MQTT broker
    • Create persistent volumes for data
  3. Access the application

    • Web UI: http://localhost:5000
    • Swagger API: http://localhost:5000/swagger
    • MQTT Broker: localhost:1883
  4. View logs

    ./docker-dev.sh logs        # Linux/macOS
    .\docker-dev.ps1 logs       # Windows
    
  5. Stop containers

    ./docker-dev.sh stop        # Linux/macOS
    .\docker-dev.ps1 stop       # Windows
    

See the Docker Development section for more commands.

Option 2: Using .NET CLI

  1. Clone the repository

    git clone https://github.com/mlmdevs/blazor-net-template.git
    cd blazor-net-template
    
  2. Set up git hooks (optional but recommended)

    ./.githooks/install.sh
    

    This installs a pre-commit hook that automatically formats code before commits.

  3. Restore dependencies

    dotnet restore
    
  4. Run the application

    dotnet run --project src/BlazorNetApp.Api
    
  5. Access the application

    • Web UI: https://localhost:5001 or http://localhost:5000
    • Swagger API: https://localhost:5001/swagger

Running Tests

# Run all tests
dotnet test

# Run with coverage
dotnet test --collect:"XPlat Code Coverage"

# Run specific test project
dotnet test tests/BlazorNetApp.Tests
dotnet test tests/BlazorNetApp.IntegrationTests

VS Code

  1. Open the project in VS Code
  2. Install recommended extensions when prompted
  3. Press F5 to start debugging
  4. The application will open automatically in your browser

JetBrains Rider

  1. Open the project in JetBrains Rider (open the BlazorNetApp.sln file)
  2. The project includes pre-configured run configurations for:
    • BlazorNetApp.Api (Debug) - Run/debug the main API project
    • All Unit Tests - Run unit tests
    • All Integration Tests - Run integration tests
    • All Tests (Unit + Integration) - Run all tests
    • Build Solution - Build the entire solution
    • Build NuGet Package - Create a NuGet package
    • Build Docker Image - Build a Docker image
    • Build Debian Package (amd64) - Create a Debian package
  3. Select a configuration from the dropdown in the toolbar and press F5 to run/debug
  4. Use Ctrl+Shift+F10 (Windows/Linux) or Cmd+Shift+F10 (macOS) to run the current test

Project Structure

blazor-net-template/
β”œβ”€β”€ src/
β”‚   └── BlazorNetApp.Api/                    # Main API project
β”‚       β”œβ”€β”€ Controllers/               # API controllers
β”‚       β”œβ”€β”€ Data/                      # Database context
β”‚       β”œβ”€β”€ Models/                    # Data models
β”‚       β”œβ”€β”€ Pages/                     # Razor Pages for UI
β”‚       β”œβ”€β”€ Services/                  # Background services (MQTT)
β”‚       └── wwwroot/                   # Static files (CSS, JS)
β”œβ”€β”€ tests/
β”‚   β”œβ”€β”€ BlazorNetApp.Tests/                 # Unit tests
β”‚   └── BlazorNetApp.IntegrationTests/      # Integration tests
β”œβ”€β”€ scripts/                           # Setup and install scripts
β”‚   β”œβ”€β”€ setup.sh                       # Master setup script
β”‚   β”œβ”€β”€ install-dotnet10.sh            # .NET 10 installation
β”‚   β”œβ”€β”€ install-sqlite3.sh             # SQLite3 installation
β”‚   β”œβ”€β”€ install-mosquitto.sh           # MQTT broker installation
β”‚   └── install-docker.sh              # Docker installation
β”œβ”€β”€ deployment/
β”‚   β”œβ”€β”€ systemd/                       # Systemd service files
β”‚   └── install.sh                     # Installation script
β”œβ”€β”€ .githooks/                         # Git hooks for code formatting
β”‚   β”œβ”€β”€ pre-commit                     # Pre-commit formatting hook
β”‚   └── install.sh                     # Hook installation script
β”œβ”€β”€ .github/workflows/                 # GitHub Actions workflows
β”‚   β”œβ”€β”€ ci-cd.yml                      # Build and test workflow
β”‚   └── release.yml                    # Release and publish workflow
β”œβ”€β”€ .vscode/                           # VS Code configuration
β”œβ”€β”€ Dockerfile                         # Docker image build
β”œβ”€β”€ docker-compose.yml                 # Docker Compose setup
β”œβ”€β”€ mosquitto.conf                     # MQTT broker config
β”œβ”€β”€ docker-dev.sh                      # Docker dev script (Linux/macOS)
β”œβ”€β”€ docker-dev.ps1                     # Docker dev script (Windows)
β”œβ”€β”€ rename-app.sh                      # Rename script (Bash)
β”œβ”€β”€ Rename-App.ps1                     # Rename script (PowerShell)
β”œβ”€β”€ build-deb.sh                       # DEB package build script
β”œβ”€β”€ build-nuget.ps1                    # NuGet package build script
└── .editorconfig                      # Code style settings

API Endpoints

TodoItems

Swagger Documentation

Configuration

appsettings.json

{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=blazor-net-app.db"
  },
  "Mqtt": {
    "Enabled": false,
    "Broker": "localhost",
    "Port": 1883,
    "ClientId": "blazor-net-app",
    "Topic": "blazor-net-app/#"
  }
}

Environment Variables

Docker Development

The project includes convenient scripts for Docker-based development with an integrated MQTT broker.

Available Commands

Linux/macOS:

./docker-dev.sh [command]

Windows (PowerShell):

.\docker-dev.ps1 -Command [command]

Commands

What’s Included

When you run docker-dev.sh start or docker-dev.ps1 start, it will:

  1. Build the .NET application Docker image
  2. Start the blazor-net-app container on port 5000
  3. Start a Mosquitto MQTT broker on port 1883
  4. Create persistent Docker volumes for:
    • Application database (blazor-net-app-data)
    • MQTT broker data (mosquitto-data)
    • MQTT broker logs (mosquitto-logs)

Accessing Services

Development Workflow

# Start development environment
./docker-dev.sh start

# Make code changes in your editor

# Rebuild and restart to test changes
./docker-dev.sh build
./docker-dev.sh restart

# View logs to debug
./docker-dev.sh logs

# Clean up when done
./docker-dev.sh clean

Testing MQTT with Docker

When using Docker, the MQTT broker is automatically configured and accessible. Test it using mosquitto clients:

# Subscribe to responses
mosquitto_sub -h localhost -t "blazor-net-app/response/#" -v

# Send a command (in another terminal)
mosquitto_pub -h localhost -t "blazor-net-app/command/getall" \
  -m '{"correlationId":"test-123"}'

MQTT Integration

The template includes comprehensive MQTT support for pub/sub messaging. When enabled, the application:

Enabling MQTT

  1. Install and run an MQTT broker (e.g., Mosquitto)
  2. Update appsettings.json to set Mqtt:Enabled to true
  3. Configure broker address and port as needed

MQTT Command Topics

The application subscribes to blazor-net-app/command/# and supports the following commands:

Get All TODO Items

Topic: blazor-net-app/command/getall Payload:

{
  "correlationId": "optional-request-id"
}

Get TODO Item by ID

Topic: blazor-net-app/command/get Payload:

{
  "id": 1,
  "correlationId": "optional-request-id"
}

Create TODO Item

Topic: blazor-net-app/command/create Payload:

{
  "title": "New TODO Item",
  "description": "Optional description",
  "isCompleted": false,
  "correlationId": "optional-request-id"
}

Update TODO Item

Topic: blazor-net-app/command/update Payload:

{
  "id": 1,
  "title": "Updated Title",
  "description": "Updated description",
  "isCompleted": true,
  "correlationId": "optional-request-id"
}

Delete TODO Item

Topic: blazor-net-app/command/delete Payload:

{
  "id": 1,
  "correlationId": "optional-request-id"
}

MQTT Responses

Responses are published to:

Success Response:

{
  "success": true,
  "data": {
    /* returned object */
  }
}

Error Response:

{
  "success": false,
  "error": "Error message"
}

Testing with Mosquitto

Install mosquitto clients:

# Ubuntu/Debian
sudo apt-get install mosquitto-clients

# macOS
brew install mosquitto

Subscribe to responses:

mosquitto_sub -h localhost -t "blazor-net-app/response/#" -v

Send a command (in another terminal):

# Create a TODO item
mosquitto_pub -h localhost -t "blazor-net-app/command/create" \
  -m '{"title":"Test via MQTT","description":"Testing","correlationId":"test-123"}'

# Get all TODO items
mosquitto_pub -h localhost -t "blazor-net-app/command/getall" \
  -m '{"correlationId":"test-456"}'

# Update a TODO item
mosquitto_pub -h localhost -t "blazor-net-app/command/update" \
  -m '{"id":1,"title":"Updated","isCompleted":true,"correlationId":"test-789"}'

# Delete a TODO item
mosquitto_pub -h localhost -t "blazor-net-app/command/delete" \
  -m '{"id":1,"correlationId":"test-999"}'

Production Deployment

Docker images are automatically built and published to GitHub Container Registry on each release, supporting both amd64 and arm64 architectures.

Pull and Run from GitHub Packages

  1. Log in to GitHub Container Registry

    echo $GITHUB_PAT | docker login ghcr.io -u USERNAME --password-stdin
    

    Replace GITHUB_PAT with a GitHub Personal Access Token with read:packages permission, and USERNAME with your GitHub username.

  2. Pull the image

    docker pull ghcr.io/mlmdevs/blazor-net-template:latest
    
  3. Run the container

    docker run -d \
      --name blazor-net-app \
      -p 8080:8080 \
      -v blazor-net-app-data:/app/data \
      -e ASPNETCORE_ENVIRONMENT=Production \
      -e Mqtt__Enabled=false \
      ghcr.io/mlmdevs/blazor-net-template:latest
    
  4. Access the application

    • Web UI: http://localhost:8080
    • Swagger API: http://localhost:8080/swagger

Docker Compose for Production

Create a docker-compose.prod.yml:

version: "3.8"

services:
  blazor-net-app:
    image: ghcr.io/mlmdevs/blazor-net-template:latest
    container_name: blazor-net-app
    ports:
      - "8080:8080"
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
      - Mqtt__Enabled=true
      - Mqtt__Broker=mosquitto
    volumes:
      - blazor-net-app-data:/app/data
    restart: unless-stopped

  mosquitto:
    image: eclipse-mosquitto:2
    container_name: blazor-net-app-mosquitto
    ports:
      - "1883:1883"
    volumes:
      - mosquitto-data:/mosquitto/data
      - ./mosquitto.conf:/mosquitto/config/mosquitto.conf:ro
    restart: unless-stopped

volumes:
  blazor-net-app-data:
  mosquitto-data:

Then run:

docker-compose -f docker-compose.prod.yml up -d

Environment Variables

Configure the application using environment variables:

Using NuGet Package (Windows)

Install as .NET Global Tool

  1. Configure GitHub Packages as a NuGet source (one-time setup)

    dotnet nuget add source "https://nuget.pkg.github.com/mlmdevs/index.json" `
      --name "GitHub-mlmdevs" `
      --username YOUR_GITHUB_USERNAME `
      --password YOUR_GITHUB_PAT `
      --store-password-in-clear-text
    

    Replace YOUR_GITHUB_USERNAME with your GitHub username and YOUR_GITHUB_PAT with a GitHub Personal Access Token with read:packages permission.

  2. Install the tool

    dotnet tool install --global BlazorNetApp --version <version>
    
  3. Run the application

    blazor-net-app
    

    The application will start and be accessible at:

    • Web UI: https://localhost:5001 or http://localhost:5000
    • Swagger API: https://localhost:5001/swagger

    Note: The database file (blazor-net-app.db) will be created in your current working directory.

  4. Update to a newer version

    dotnet tool update --global BlazorNetApp
    
  5. Uninstall

    dotnet tool uninstall --global BlazorNetApp
    

Install from Release Assets

Alternatively, you can download the .nupkg file from the releases page and install it locally:

dotnet tool install --global --add-source ./path/to/folder BlazorNetApp

Replace ./path/to/folder with the directory containing the downloaded .nupkg file.

Using DEB Package (Ubuntu/Debian)

  1. Download the latest release from the releases page

  2. Install the package

    sudo dpkg -i blazor-net-app_<version>_<arch>.deb
    

    Note: The DEB package is self-contained and includes .NET 10 runtime. No additional dependencies are required.

    The service runs in Production mode and stores the database at /var/lib/blazor-net-app/blazor-net-app.db.

  3. Manage the service

    sudo systemctl status blazor-net-app
    sudo systemctl restart blazor-net-app
    sudo systemctl stop blazor-net-app
    sudo systemctl start blazor-net-app
    
  4. View logs

    sudo journalctl -u blazor-net-app -f
    

Manual Installation

  1. Publish the application

    dotnet publish src/BlazorNetApp.Api/BlazorNetApp.Api.csproj \
      --configuration Release \
      --output publish \
      --runtime linux-x64 \
      --self-contained true
    
  2. Run the installation script

    sudo ./deployment/install.sh
    

Development

Adding New Features

  1. Create a new model in src/BlazorNetApp.Api/Models/
  2. Add DbSet to ApplicationDbContext
  3. Create a controller in src/BlazorNetApp.Api/Controllers/
  4. Update UI in src/BlazorNetApp.Api/Pages/ and wwwroot/
  5. Write tests in tests/

Code Style

The project uses EditorConfig for consistent code formatting.

Format check:

dotnet format --verify-no-changes

Auto-format code:

dotnet format

Pre-commit hook (automatic formatting):

Set up the pre-commit hook to automatically format code before each commit:

./.githooks/install.sh

After installation, any commit will trigger automatic code formatting. If issues are found, they will be fixed automatically, and you’ll need to review and stage the changes before committing again.

Database Migrations

# Create a migration
cd src/BlazorNetApp.Api
dotnet ef migrations add MigrationName

# Apply migrations
dotnet ef database update

GitHub Actions

The project includes two workflows:

  1. CI/CD (ci-cd.yml) - Runs on push/PR

    • Builds the solution
    • Runs all tests
    • Checks code formatting
    • Publishes artifacts
  2. Release (release.yml) - Runs on version tags

    • Builds and pushes Docker images (amd64 & arm64) to GitHub Container Registry
    • Builds DEB packages for amd64 and arm64
    • Pushes DEB packages to APT repository
    • Builds and pushes NuGet package to GitHub Packages
    • Creates GitHub release with all packages

To create a release:

git tag -a v1.0.0 -m "Release version 1.0.0"
git push origin v1.0.0

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

Support

For issues and questions: