# 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 --name 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>
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.dllpublicIConfiguration Configuration { get; }
publicStartup(IConfigurationconfiguration)
{
Configuration = configuration;
}
// recherche Key, si Key n'a pas été trouvé affecte default value à la variable valuevarvalue = Configuration.GetValue<string>("Key", "default value");
varvalue = Configuration["Key"];
// pour les connection strings
Configuration.GetConnectionString("SqlServer1")
// dotnet add package System.Data.SqlClientvar builder = newSqlConnectionStringBuilder(Configuration.GetConnectionString("SqlServer4")); // from appsettings.json
builder.Password = Configuration["DbPassword"]; // from secrets storage in Dev and appsettings.json in Prod varconnectionString = builder.ConnectionString;
Useful in dev environment to not store password in source code.
# aller dans le dossier contenant le *.csprojcd 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 DevelopmentpublicstaticIHostBuilderCreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
Creates a platform-specific executable with only the application binaries and its dependencies.
lighter deployment: only the application binaries and its dependencies are deployed
the .NET runtime security updates are managed by the system
the required .NET runtime of the application has to match the installed .NET runtime
dotnet publish -c Release -r linux-arm64 --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]/[runtime]/publish )
System.MissingMethodException: Cannot dynamically create an instance of type 'Microsoft.AspNetCore.Components.Web.HeadOutlet'.
Reason: No parameterless constructor defined.
App.razor
@using System.Diagnostics.CodeAnalysis;@code {
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(HeadOutlet))] // Prevent HeadOutlet from being trimmedprotectedoverridevoidOnInitialized() { }
}
By default, an app is logging into Console, Debug, EventSource, EventLog (only when running on Windows).
This include the linux journal for production and the VS code DEBUG CONSOLE for development.
publicclassMyClass
{
privatereadonlyILoggerlogger;
publicMyClass(ILogger<MyClass> logger)
{
this.logger = logger;
}
publicvoidMyMethod()
{
// to optimize the performances, test if the log level is enabledif (logger.IsEnabled(LogLevel.Debug)) logger.LogDebug("Debug");
logger.LogTrace("Trace");
logger.LogInformation("Info");
logger.LogWarning("Warn");
logger.LogError("Error");
logger.LogCritical("Fatal");
}
}
appsettings.json
{"Logging":{"LogLevel":{"Default":"Information",// log level par défaut"Microsoft":"Warning",// pour les loggers commençant par Microsoft"MyNamespace.MyClass":"Debug"// pour les loggers de MyClass}}
Program.cs
publicstaticIHostBuilderCreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.ClearProviders(); // remove all the providers: no more logs
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
The Log methods are synchronous.
There is no file log provider.
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
# create the unit tests project for MyService
dotnet new xunit -o MyService.Tests
# add a reference to the project to testcd MyService.Tests
dotnet add reference ../MyService/MyService.csproj
cd ..
# create a solution if you don't have one yet
dotnet new sln --name MySolution
# add the unit tests project to the solution
dotnet sln add ./MyService.Tests/MyService.Tests.csproj
# run all the unit tests
dotnet test# run the unit tests of a specific namespace / class
dotnet test --filter Namespace.Class
# Top level entry required to mark this as a global AnalyzerConfig fileis_global = true# NOTE: No section headers for configuration entries#### .NET Coding Conventions ##### this. and Me. preferencesdotnet_style_qualification_for_method = true:warning
#### Diagnostic configuration ##### CA2007: Do not directly await a Taskdotnet_diagnostic.CA2007.severity = none
Code style analysis
# verify that all code is correctly formatted
dotnet format --verify-no-changes
# format all code
dotnet format
is_global = true# enable all analyzers by default and set the severity to warningroslynator_analyzers.enabled_by_default = truedotnet_analyzer_diagnostic.category-roslynator.severity = warning
# enable all refactoringsroslynator_refactorings.enabled = true# enable all compiler diagnostic fixesroslynator_compiler_diagnostic_fixes.enabled = true# Optionsroslynator_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 = trueroslynator_blank_line_between_closing_brace_and_switch_section = falseroslynator_blank_line_between_single_line_accessors = falseroslynator_blank_line_between_using_directives = never
roslynator_block_braces_style = single_line_when_empty
#roslynator_body_style = block|expressionroslynator_conditional_operator_condition_parentheses_style = omit
roslynator_conditional_operator_new_line = beforeroslynator_configure_await = falseroslynator_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 = 140roslynator_new_line_at_end_of_file = falseroslynator_new_line_before_while_in_do_statement = falseroslynator_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 = falseroslynator_suppress_unity_script_methods = trueroslynator_use_anonymous_function_or_method_group = method_group
roslynator_use_block_body_when_declaration_spans_over_multiple_lines = trueroslynator_use_block_body_when_expression_spans_over_multiple_lines = trueroslynator_use_var_instead_of_implicit_object_creation = true# Analyzers# Add blank line between single-line declarationsdotnet_diagnostic.rcs0012.severity = none
# Remove braces from if-elsedotnet_diagnostic.rcs1004.severity = none
# Use explicit type instead of 'var' (when the type is not obvious)dotnet_diagnostic.rcs1008.severity = none
# Use explicit type instead of 'var' (foreach variable)dotnet_diagnostic.rcs1009.severity = none
# Use explicit type instead of 'var' (when the type is obvious)dotnet_diagnostic.rcs1012.severity = none
# Avoid unnecessary boxing of value typedotnet_diagnostic.rcs1198.severity = none
# Mark publicly visible type with DebuggerDisplay attributedotnet_diagnostic.rcs1223.severity = none
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/
# backup the provided System.Composition.AttributedModel.dll which is in version 6.0mv System.Composition.AttributedModel.dll System.Composition.AttributedModel-6.0.dll
# replace it by its version 7.0cp /usr/share/dotnet/sdk/7.0.105/DotnetTools/dotnet-format/System.Composition.AttributedModel.dll .
# add the XunitXML.TestLogger nuget package to the unit test project
dotnet add package XunitXML.TestLogger
# run unit tests with Coverlet data collector and log the results
dotnet test MySolution.sln --collect="XPlat Code Coverage" --logger:"xunit;LogFilePath=TestResults.xml"# creates a TestResults.xml report and a TestResults/[guid]/coverage.cobertura.xml report# extract the line coverage:
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
# install the ReportGenerator tool
dotnet tool install -g dotnet-reportgenerator-globaltool
# get a text summary report from all the cobertura reports
reportgenerator -reports:"*/TestResults/*/coverage.cobertura.xml" -targetdir:CoverageReport -reporttypes:TextSummary
# creates CoverageReport/TextSummary.txt# extract the line coverage:
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.
# 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 ARMcd 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)