.NET Notes
Getting Started with .NET on Ubuntu
Install the .NET SDK
Ubuntu ships .NET directly in its own package feeds — no Microsoft repository setup needed.
Ubuntu 24.04 / 25.04 / 25.10 / 26.04
# .NET 10 (LTS) - available in the built-in Ubuntu feed
sudo apt-get update && sudo apt-get install -y dotnet-sdk-10.0
# .NET 9 - on 24.04 and 22.04 you need the backports PPA first
sudo add-apt-repository ppa:dotnet/backports
sudo apt-get update && sudo apt-get install -y dotnet-sdk-9.0
# .NET 8 - available in the built-in Ubuntu feed
sudo apt-get update && sudo apt-get install -y dotnet-sdk-8.0
Ubuntu 22.04
# .NET 8 is in the built-in feed
sudo apt-get update && sudo apt-get install -y dotnet-sdk-8.0
# .NET 9 / 10 require the backports PPA
sudo add-apt-repository ppa:dotnet/backports
sudo apt-get update && sudo apt-get install -y dotnet-sdk-9.0
Verify the install:
dotnet --version
dotnet --list-sdks
dotnet --list-runtimes
Package naming convention: {product}-{type}-{version}
dotnet-sdk-10.0 # .NET 10 SDK
aspnetcore-runtime-9.0 # ASP.NET Core 9 runtime (includes .NET runtime)
dotnet-runtime-9.0 # .NET 9 runtime only (no ASP.NET Core)
Create Your First Project
# Console app
dotnet new console -n HelloWorld
cd HelloWorld
# Run it
dotnet run
# Hello, World!
Common project templates:
| Command | Description |
|---|---|
dotnet new console |
Console application |
dotnet new web |
Minimal ASP.NET Core web app |
dotnet new webapi |
REST API with controllers |
dotnet new mvc |
ASP.NET Core MVC |
dotnet new classlib |
Class library |
dotnet new xunit |
xUnit test project |
Project Structure
HelloWorld/
├── HelloWorld.csproj # Project file (dependencies, SDK, target)
├── Program.cs # Entry point
└── obj/ # Build intermediates (git-ignore this)
A minimal Program.cs using top-level statements (default since .NET 6):
Console.WriteLine("Hello, World!");
The .csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>
Essential CLI Commands
dotnet new <template> # Scaffold a project
dotnet build # Compile the project
dotnet run # Build + run
dotnet test # Run tests
dotnet publish # Produce deployable output
dotnet add package <name> # Add a NuGet package
dotnet restore # Restore NuGet dependencies
dotnet clean # Delete build artifacts
Adding NuGet Packages
# Add a package
dotnet add package Newtonsoft.Json
# List installed packages
dotnet list package
# Remove a package
dotnet remove package Newtonsoft.Json
Packages are restored from nuget.org and recorded in the .csproj:
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
Build a Minimal Web API
dotnet new webapi -n MyApi --use-minimal-apis
cd MyApi
dotnet run
The default Program.cs in a minimal API:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello from .NET!");
app.MapGet("/greet/{name}", (string name) => $"Hello, {name}!");
app.Run();
Visit http://localhost:5000 or check the port printed in the terminal.
Solutions and Multiple Projects
A solution (.sln) groups related projects.
# Create a solution
dotnet new sln -n MyApp
# Create projects
dotnet new webapi -n MyApp.Api
dotnet new classlib -n MyApp.Core
dotnet new xunit -n MyApp.Tests
# Add them to the solution
dotnet sln add MyApp.Api/MyApp.Api.csproj
dotnet sln add MyApp.Core/MyApp.Core.csproj
dotnet sln add MyApp.Tests/MyApp.Tests.csproj
# Reference one project from another
dotnet add MyApp.Api/MyApp.Api.csproj reference MyApp.Core/MyApp.Core.csproj
Publish and Run
Build a self-contained binary:
# Framework-dependent (requires .NET runtime on the host)
dotnet publish -c Release -o ./out
# Self-contained single file for Linux x64
dotnet publish -c Release -r linux-x64 --self-contained true -p:PublishSingleFile=true -o ./out
./out/MyApp
Useful Environment Variables
# Change the URLs the app listens on
export ASPNETCORE_URLS="http://0.0.0.0:8080"
# Set environment (Development / Staging / Production)
export ASPNETCORE_ENVIRONMENT=Development
# Point to a custom NuGet cache
export NUGET_PACKAGES=~/.nuget/packages
Install Multiple SDK Versions
# Install a specific SDK version alongside the current one
sudo apt install dotnet-sdk-8.0
# List all installed SDKs
dotnet --list-sdks
# Pin a project to a specific version with a global.json
dotnet new globaljson --sdk-version 8.0.x
global.json controls which SDK version dotnet uses in that directory:
{
"sdk": {
"version": "8.0.0",
"rollForward": "latestMinor"
}
}
Tips
- Enable nullable reference types (
<Nullable>enable</Nullable>) in every new project - catches null bugs at compile time. ImplicitUsingsauto-imports common namespaces (System,System.Linq, etc.) so you don’t have to.- Hot reload works in development:
dotnet watch runrestarts the app on file save. dotnet formatenforces code style (runs on CI too).- Secrets in development:
dotnet user-secrets initkeeps credentials out ofappsettings.json.