Links
dotnet CLI
|
# help
dotnet -h
# get versions of .NET SDK, Host, .NET runtimes installed
dotnet --info
# list available templates (webapi, blazor)
dotnet new
# create a new Web API project
dotnet new webapi -o [project-name] --no-https
# create a solution file and folder
dotnet new sln -o MySolution
# add a project to the solution
dotnet sln add ./MyProject/MyProject.csproj
# add a reference to another project
dotnet add reference ../otherproject/otherproject.csproj
# restore and build
dotnet build
# restore, build and run
dotnet run
# force url and port (default: http://127.0.0.1:5000)
ASPNETCORE_URLS="http://127.0.0.1:5123" dotnet run # linux
dotnet run --ASPNETCORE_ENVIRONMENT Development # powershell
$env:ASPNETCORE_URLS="http://127.0.0.1:5123" ; dotnet run # powershell
|
Nuget packages
|
# ajouter un package NuGet
dotnet add package <package_name>
dotnet add package <package_name> --version 2.0.0
# lists the NuGet packages
dotnet list package
# lists packages that have newer versions available
dotnet list package --outdated
# supprimer un package
dotnet remove package <package_name>
|
Allows you to manage the versions of Nuget packages in a single centralized file.
Directory.Build.targets
|
<!-- Directory.Build.targets file has to be at the solution root -->
<Project>
<ItemGroup>
<PackageReference Update="AutoMapper" Version="10.1.1" />
|
MyProject/MyProject.csproj
|
<Project Sdk="Microsoft.NET.Sdk.Web">
<ItemGroup>
<!-- remove the version -->
<PackageReference Include="AutoMapper" />
|
Sources des settings par défaut dans l'ordre de lecture:
- appsettings.json
- appsettings.<EnvironmentName>.json
- UserSecrets in Development environment
- Environment variables
- Command-line arguments
|
Les settings de la source suivante écrasent ceux déjà chargés. |
Startup.cs
|
using Microsoft.Extensions.Configuration; // Microsoft.Extensions.Configuration.Abstractions.dll
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
// recherche Key, si Key n'a pas été trouvé affecte default value à la variable value
var value = Configuration.GetValue<string>("Key", "default value");
var value = Configuration["Key"];
// pour les connection strings
Configuration.GetConnectionString("SqlServer1")
// dotnet add package System.Data.SqlClient
var builder = new SqlConnectionStringBuilder(Configuration.GetConnectionString("SqlServer4")); // from appsettings.json
builder.Password = Configuration["DbPassword"]; // from secrets storage in Dev and appsettings.json in Prod
var connectionString = builder.ConnectionString;
|
appsettings.json
appsettings.json
|
{
"Key": "Value",
"ConnectionStrings": {
"SqlServer1": "Server=(localdb)\\MSSQLLocalDB;Database=MyDb;Integrated Security=True;MultipleActiveResultSets=True",
"SqlServer2": "Server=(localdb)\\mssqllocaldb;Database=MyDb;Trusted_Connection=True;",
"SqlServer3": "Server=localhost;Database=MyDb;User=sa;Password=pwd;",
"SqlServer4": "server=localhost;database=MyDb;user=sa;",
"MySql": "Server=localhost;Database=MyDb;User=root;Password=pwd;",
"Sqlite": "Data Source=MyDb.db"
},
"DbPassword": "****"
}
|
Useful for using a file other than appsettings.config or for Console projects.
Program.cs
|
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureHostConfiguration(configHost =>
{
configHost.SetBasePath(Directory.GetCurrentDirectory());
configHost.AddJsonFile("passwords.json", optional: true);
})
.UseStartup<Startup>();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddJsonFile("passwords.json", optional: false, reloadOnChange: false);
config.AddXmlFile("appsettings.xml", optional: true, reloadOnChange: true);
})
.UseStartup<Startup>();
}
|
Useful in dev environment to not store password in source code.
|
# aller dans le dossier contenant le *.csproj
cd MyProject
# adds a UserSecretsId element within a PropertyGroup of the .csproj file
dotnet user-secrets init
# set a secret
# put a space as first character so the command line is not saved in the history
dotnet user-secrets set "key" "secret"
# the whole connection string
dotnet user-secrets set "ConnectionStrings:SqlServer" "server=localhost;database=test;user=test;password=****"
# only the connection string password
dotnet user-secrets set "DbPassword" "****"
# the secrets are stored in a JSON configuration file in a system-protected user profile folder on the local machine
# Windows: %APPDATA%\microsoft\UserSecrets\<userSecretsId>\secrets.json
# Linux: ~/.microsoft/usersecrets/<userSecretsId>/secrets.json
# list all secrets of the current project
dotnet user-secrets list
# remove a secret in the current project
dotnet user-secrets remove "key"
# remove all secrets of the current project
dotnet user-secrets clear
|
WebApi/Program.cs
|
// The user secrets configuration source is automatically added in development mode
// when the project calls CreateDefaultBuilder to initialize a new instance of the host with preconfigured defaults.
// CreateDefaultBuilder calls AddUserSecrets when the EnvironmentName is Development
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
|
Console/Program.cs
|
public static IConfigurationRoot Configuration { get; set; }
private static void Main()
{
var builder = new ConfigurationBuilder();
// dotnet add package Microsoft.Extensions.Configuration.UserSecrets
builder.AddUserSecrets<Program>();
Configuration = builder.Build();
|
|
dotnet MyApp MyKey="value"
|
L’environnement utilisé est contenu dans la variable environnement ASPNETCORE_ENVIRONMENT
3 valeurs sont supportées par le framework:
- Development
- Staging
- Production (valeur par défaut)
|
# lancer le service avec l'environnement Development
ASPNETCORE_ENVIRONMENT=Development dotnet run
dotnet run --ASPNETCORE_ENVIRONMENT Development
|
Configuration pour la ligne de commande:
Properties/launchSettings.json
|
{
"profiles": {
"my_project": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "api/values",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
|
Configuration pour vs code:
.vscode/launch.json
|
"configurations": [
{
"name": ".NET Core Launch (web)",
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
]
|
Configuration pour vs:
VS → Projet Properties → Debug → Environment variables → ASPNETCORE_ENVIRONMENT = Development
Deployment Scripts
MyProject.csproj
|
<Target Name="MyPublishScripts" AfterTargets="BeforePublish">
<Exec Command="npm install" />
<Exec Command="gulp minify" />
<Exec Command="ng build" />
</Target>
|
Applications can be published in two different modes: self-contained or runtime-dependent.
- self-contained includes the .NET Core runtime and libraries, and your application and its dependencies. Users of the application can run it on a machine that doesn't have the .NET Core runtime installed.
- runtime-dependent includes only your application itself and its dependencies. Users of the application have to separately install the .NET Core runtime.
|
# publier dans le dossier bin\Debug\netcoreapp2.0\publish
dotnet publish -c Release -r linux-arm --self-contained false
# -c : configuration : Debug (default), Release
# -r <RUNTIME_IDENTIFIER> : publishes the application for a given runtime
# --self-contained [true|false] : publishes the .NET Core runtime with the application (default true if a runtime identifier is specified and the project is an executable project)
# -o /path/folder : output directory (default: bin/[configuration]/[framework]/publish or bin/[configuration]/[framework]/[runtime]/publish )
# rendre l'exécutable exécutable pour tous
chmod +x bin/Release/netcoreapp2.1/ubuntu.16.04-x64/publish/myproject
|
MyProject.csproj
|
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<RuntimeIdentifier>win10-x64,ubuntu-x64,linux-x64</RuntimeIdentifier>
</PropertyGroup>
|
|
Par défaut la publication se fait en mode runtime-dependent: le dossier contient seulement les dll du projet.
En spécifiant le runtime la publication se fait en mode self-contained: le dossier contient toutes les dll nécessaire ainsi qu'un exécutable adapté au runtime. |
RID Catalog (list): ubuntu-18.04-arm64, arch-x64, win10-x64
Define the port on deployed application
By defaut the following urls are used: http://localhost:5000 https://localhost:5001
appsettings.json
|
{
"Kestrel": {
"EndPoints": {
"Http": {
"Url": "http://localhost:6000"
|
It can also be configured in the service file.
Linux
/etc/systemd/system/kestrel-myproject.service
|
[Unit]
Description=My Project description
[Service]
WorkingDirectory=/srv/myproject
ExecStart=/srv/myproject/myproject
ExecStart=/usr/bin/dotnet /srv/myproject/myproject.dll
Restart=always
RestartSec=10 # Restart service after 10 seconds if dotnet service crashes
KillSignal=SIGINT
SyslogIdentifier=myproject
User=http
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
Environment=ASPNETCORE_URLS=http://localhost:5001
Environment=ConnectionStrings__MyConnectionString=server\x3dlocalhost\x3bdatabase\x3dMyDb\x3buser\x3dMyUser\x3bpassword\x3dMyPwd
[Install]
WantedBy=multi-user.target
|
|
# escape value as connection string
systemd-escape "<value-to-escape>"
|
MyProject.csproj
|
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyVersion>1.1.1.1</AssemblyVersion>
<FileVersion>2.2.2.2</FileVersion>
<Version>3.3.3.3-xyz</Version>
</PropertyGroup>
</Project>
|
|
typeof(Startup).Assembly.GetName().Version; // 1.1.1.1
Assembly.GetEntryAssembly().GetName().Version; // 1.1.1.1
Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version; // 2.2.2.2
Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion; // 3.3.3.3-xyz
|
Nuget
|
# Display locals for all folders
dotnet nuget locals all --list
# http-cache: /home/[user]/.local/share/NuGet/http-cache
# global-packages: /home/[user]/.nuget/packages/
# temp: /tmp/NuGetScratch
# plugins-cache: /home/[user]/.local/share/NuGet/plugin-cache
# Clear all caches
dotnet nuget locals all --clear
# Clear the global packages folder
dotnet nuget locals global-packages --clear
|
Git
.gitignore
|
# Build results
bin/
obj/
# .NET Core
Properties/launchSettings.json
# Log files
*.log
|
|
The Log methods are synchronous.
There is no file log provider. |
By default, an app is logging into Console, Debug, EventSource, EventLog (only when running on Windows).
Program.cs
|
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.ClearProviders(); // remove all the providers: no more logs
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
|
|
public class MyClass
{
private readonly ILogger logger;
public MyClass(ILogger<MyClass> logger)
{
this.logger = logger;
}
public void MyMethod()
{
logger.LogDebug("Debug");
logger.LogTrace("Trace");
logger.LogInformation("Info");
logger.LogWarning("Warn");
logger.LogError("Error");
logger.LogCritical("Fatal");
}
}
|
config.json
|
{
"Logging": {
"LogLevel": {
"Default": "Information", // log level par défaut
"Microsoft": "Warning", // pour les loggers commençant par Microsoft
"MyClass": "Debug" // pour les loggers commençant par MyClass
}
}
|
Console |
- VS code "DEBUG CONSOLE" tab
- In the console window when the app is run with dotnet run
|
Debug |
Debug window when debugging in Visual Studio On Linux journal or /var/log/message or /var/log/syslog
|
EventSource |
Event Tracing for Windows (ETW)
|
EventLog |
Windows Event Log
|
TraceSource |
System.Diagnostics.TraceSource libraries and providers ()
|
Azure App Service |
text files in an Azure App Service app's file system and to blob storage in an Azure Storage account
|
journal
mar 19 17:53:10 hostname logtest[29321]: fail: LogTest.Controllers.ItemController[0]
mar 19 17:53:10 hostname logtest[29321]: Log message
mar 19 17:58:27 hostname logtest[29321]: fail: Microsoft.AspNetCore.Server.Kestrel[13]
mar 19 17:58:27 hostname logtest[29321]: Connection id "...", Request id "...": An unhandled exception was thrown by the application.
mar 19 17:58:27 hostname logtest[29321]: System.Exception: exception message
mar 19 17:58:27 hostname logtest[29321]: at LogTest.Controllers.ItemController.ThrowException() in /dev-path/LogTest/Controllers/ItemController.cs:line 41
apache log
- access.log is well filled by each query
- error.log is never filled
Unit tests
|
# create the unit tests project for MyService
dotnet new xunit -o MyService.Tests
# add a reference to the project to test
cd MyService.Tests
dotnet add reference ../MyService/MyService.csproj
cd ..
# create a solution if you don't have one yet
dotnet new sln -o MySolution
# add the unit tests project to the solution
dotnet sln add ./MyService.Tests/MyService.Tests.csproj
# run the unit tests
dotnet test
|
ARM
|
# créé un dossier /bin/Debug/netcoreapp2.0/linux-arm/publish/ contenant l’exécutable et ses dépendances pour ARM
dotnet publish -r linux-arm
# copier le dossier linux-arm sur le serveur ARM
cd linux-arm/publish
./MyApp
# [1] 8952 segmentation fault (core dumped) ./MyApp
# systemd-coredump[8962]: Failed to parse PID "0": Numerical result out of range
# Unhandled Exception: [1] 9060 segmentation fault (core dumped) ./MyApp
# systemd-coredump[9083]: Failed to parse PID "0": Numerical result out of range
|
Description
Réécriture de ASP.NET:
- moderne, plus besoin de conserver la compatibilité
- léger, l'application ne charge que ce dont elle a besoin (packages MVC, Logging, Identity)
- performant
- cross platform et open source
- MVC et Web API, plus de WebForm
Installation
|
pacman -S aspnet-runtime dotnet-sdk
# installe dotnet-host dotnet-runtime aspnet-runtime dotnet-sdk
|
|
Ajouter ~/.dotnet/tools à PATH pour que les dotnet tools fonctionnent depuis le shell. |
|
Les assembly sont installées dans /usr/share/dotnet/shared/Microsoft.NETCore.App/x.y.z |
/etc/environment
|
# disable .net core telemetry
DOTNET_CLI_TELEMETRY_OPTOUT=1
|
- Visual Studio Installer → Workloads → ASP.NET and web development
|
# version de .net core installée
dotnet --version
|