Links
dotnet CLI
|
dotnet -h
dotnet --info
dotnet new
dotnet new webapi -o [project-name] --no-https
dotnet new sln --name MySolution
dotnet sln add ./MyProject/MyProject.csproj
dotnet add reference ../otherproject/otherproject.csproj
dotnet build
dotnet run
ASPNETCORE_URLS="http://127.0.0.1:5123" dotnet run
dotnet run --ASPNETCORE_ENVIRONMENT Development
$env:ASPNETCORE_URLS="http://127.0.0.1:5123" ; dotnet run
|
Nuget packages
|
dotnet add package <package_name>
dotnet add package <package_name> --version 2.0.0
dotnet list package
dotnet list package --outdated
dotnet remove package <package_name>
|
Allows you to manage the versions of Nuget packages in a single centralized file.
Directory.Build.targets
|
<Project>
<ItemGroup>
<PackageReference Update="AutoMapper" Version="10.1.1" />
|
MyProject/MyProject.csproj
|
<Project Sdk="Microsoft.NET.Sdk.Web">
<ItemGroup>
<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;
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
var value = Configuration.GetValue<string>("Key", "default value");
var value = Configuration["Key"];
Configuration.GetConnectionString("SqlServer1")
// dotnet add package System.Data.SqlClient
var builder = new SqlConnectionStringBuilder(Configuration.GetConnectionString("SqlServer4"));
builder.Password = Configuration["DbPassword"];
var connectionString = builder.ConnectionString;
|
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.
|
cd MyProject
dotnet user-secrets init
dotnet user-secrets set "key" "secret"
dotnet user-secrets set "ConnectionStrings:SqlServer" "server=localhost;database=test;user=test;password=****"
dotnet user-secrets set "DbPassword" "****"
dotnet user-secrets list
dotnet user-secrets remove "key"
dotnet user-secrets clear
|
WebApi/Program.cs
|
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();
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)
|
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>
|
Creates a platform-specific executable with only your application binaries and its dependencies.
Host machine of the application have to have installed the corresponding .NET runtime.
|
dotnet publish -c Release -r linux-arm64 --self-contained false
|
RID Catalog (list): linux-arm64, linux-x64, win10-x64
Creates a platform-specific executable with all the required .NET files to run your app but it doesn't include the native dependencies of .NET. These dependencies must be present on the system before the app runs.
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.
|
dotnet publish -c Release -r linux-arm64 --self-contained true -p:PublishTrimmed=true
|
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
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
|
|
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;
Assembly.GetEntryAssembly().GetName().Version;
Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version;
Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
|
Nuget
|
dotnet nuget locals all --list
dotnet nuget locals all --clear
dotnet nuget locals global-packages --clear
|
Git
.gitignore
|
bin/
obj/
Properties/launchSettings.json
*.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();
})
.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",
"Microsoft": "Warning",
"MyClass": "Debug"
}
}
|
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
|
dotnet new xunit -o MyService.Tests
cd MyService.Tests
dotnet add reference ../MyService/MyService.csproj
cd ..
dotnet new sln --name MySolution
dotnet sln add ./MyService.Tests/MyService.Tests.csproj
dotnet test
|
Code quality analysis
Those rules are enabled by default.
Here is how to enabled additional rules:
MyProject.csproj
|
<PropertyGroup>
<AnalysisLevel>latest-All</AnalysisLevel>
</PropertyGroup>
|
Code style analysis
|
dotnet format --verify-no-changes
dotnet format
|
.editorconfig
|
root = true
[*]
charset = utf-8
insert_final_newline = false
[*.{cs,vb}]
dotnet_analyzer_diagnostic.severity = warning
dotnet_naming_style.upper_case_style.capitalization = all_upper
dotnet_naming_style.camel_case_style.capitalization = camel_case
dotnet_naming_symbols.constant_fields.applicable_kinds = field
dotnet_naming_symbols.constant_fields.required_modifiers = const
dotnet_naming_rule.constant_fields_should_be_upper_case.symbols = constant_fields
dotnet_naming_rule.constant_fields_should_be_upper_case.style = upper_case_style
dotnet_naming_rule.constant_fields_should_be_upper_case.severity = warning
dotnet_naming_symbols.local_symbol.applicable_kinds = local
dotnet_naming_rule.variables_should_be_camel_case.symbols = local_symbol
dotnet_naming_rule.variables_should_be_camel_case.style = camel_case_style
dotnet_naming_rule.variables_should_be_camel_case.severity = warning
dotnet_naming_symbols.parameter_symbol.applicable_kinds = parameter
dotnet_naming_rule.parameters_should_be_camel_case.symbols = parameter_symbol
dotnet_naming_rule.parameters_should_be_camel_case.style = camel_case_style
dotnet_naming_rule.parameters_should_be_camel_case.severity = warning
[*.cs]
csharp_style_namespace_declarations = file_scoped
csharp_style_var_for_built_in_types = true
csharp_style_var_when_type_is_apparent = true
csharp_style_var_elsewhere = true
csharp_style_expression_bodied_local_functions = when_on_single_line
csharp_style_expression_bodied_methods = when_on_single_line
dotnet_diagnostic.IDE0058.severity = none
|
Visual Studio Code integration
settings.json
|
"omnisharp.enableRoslynAnalyzers": true,
"omnisharp.enableEditorConfigSupport": true,
|
- Install the Roslynator extension in Visual Studio Code
- Configure Roslynator on a user-wide basis
- vscode → Ctrl + Shift + P → enter roslynator → select Roslynator: Open Default Configuration File (.roslynatorconfig)
~/.local/share/JosefPihrt/Roslynator/.roslynatorconfig
|
is_global = true
roslynator_analyzers.enabled_by_default = true
dotnet_analyzer_diagnostic.category-roslynator.severity = warning
roslynator_refactorings.enabled = true
roslynator_compiler_diagnostic_fixes.enabled = true
roslynator_accessibility_modifiers = explicit
roslynator_accessor_braces_style = single_line_when_expression_is_on_single_line
roslynator_array_creation_type_style = implicit_when_type_is_obvious
roslynator_arrow_token_new_line = before
roslynator_binary_operator_new_line = before
roslynator_blank_line_after_file_scoped_namespace_declaration = true
roslynator_blank_line_between_closing_brace_and_switch_section = false
roslynator_blank_line_between_single_line_accessors = false
roslynator_blank_line_between_using_directives = never
roslynator_block_braces_style = single_line_when_empty
roslynator_conditional_operator_condition_parentheses_style = omit
roslynator_conditional_operator_new_line = beforeroslynator_configure_await = false
roslynator_doc_comment_summary_style = multi_line
roslynator_empty_string_style = field
roslynator_enum_flag_value_style = decimal_number
roslynator_enum_has_flag_style = method
roslynator_equals_token_new_line = before
roslynator_infinite_loop_style = while
roslynator_max_line_length = 140
roslynator_new_line_at_end_of_file = false
roslynator_new_line_before_while_in_do_statement = false
roslynator_null_conditional_operator_new_line = before
roslynator_null_check_style = pattern_matching
roslynator_object_creation_parentheses_style = omit
roslynator_object_creation_type_style = implicit_when_type_is_obvious
roslynator_prefix_field_identifier_with_underscore = false
roslynator_suppress_unity_script_methods = true
roslynator_use_anonymous_function_or_method_group = method_group
roslynator_use_block_body_when_declaration_spans_over_multiple_lines = true
roslynator_use_block_body_when_expression_spans_over_multiple_lines = true
roslynator_use_var_instead_of_implicit_object_creation = true
dotnet_diagnostic.rcs0012.severity = none
dotnet_diagnostic.rcs1004.severity = none
dotnet_diagnostic.rcs1008.severity = none
dotnet_diagnostic.rcs1009.severity = none
dotnet_diagnostic.rcs1012.severity = none
dotnet_diagnostic.rcs1198.severity = none
dotnet_diagnostic.rcs1223.severity = none
|
|
dotnet tool install -g roslynator.dotnet.cli
roslynator analyze \
--analyzer-assemblies \
~/.vscode/extensions/josefpihrt-vscode.roslynator-4.3.0/roslyn/common \
~/.vscode/extensions/josefpihrt-vscode.roslynator-4.3.0/roslyn/analyzers
|
 |
To fix the error:
Could not load file or assembly 'System.Composition.AttributedModel, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
The system cannot find the file specified.
|
cd ~/.dotnet/tools/.store/roslynator.dotnet.cli/0.6.0/roslynator.dotnet.cli/0.6.0/tools/net7.0/any/
mv System.Composition.AttributedModel.dll System.Composition.AttributedModel-6.0.dll
cp /usr/share/dotnet/sdk/7.0.105/DotnetTools/dotnet-format/System.Composition.AttributedModel.dll .
| |
Code coverage
|
dotnet add package XunitXML.TestLogger
dotnet test MySolution.sln --collect="XPlat Code Coverage" --logger:"xunit;LogFilePath=TestResults.xml"
xmllint --xpath "string(/coverage/@line-rate)" TestResults/[guid]/coverage.cobertura.xml
sed -n -r 's/<coverage line-rate="([0-9.]+)".*/\1/p' TestResults/[guid]/coverage.cobertura.xml
dotnet tool install -g dotnet-reportgenerator-globaltool
reportgenerator -reports:"*/TestResults/*/coverage.cobertura.xml" -targetdir:CoverageReport -reporttypes:TextSummary
sed -n -r 's/Line coverage: ([0-9.]+)%/\1/p' CoverageReport/Summary.txt
|
Ignore generated code
Create an .editorconfig file in a folder to not run code analysis on the files of this folder.
MyWebapi/DataAccess/.editorconfig
|
[*]
generated_code = true
dotnet_analyzer_diagnostic.severity = silent
|
ARM
|
dotnet publish -r linux-arm
cd linux-arm/publish
./MyApp
|
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
Erreur lors de la création de la vignette : /bin/bash: /usr/bin/convert: No such file or directory Error code: 127
Installation
|
pacman -S 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
|
DOTNET_CLI_TELEMETRY_OPTOUT=1
|
- Visual Studio Installer → Workloads → ASP.NET and web development
|
dotnet --version
|