Asp Net Core FR
Asp Net Core FR
Asp Net Core FR
net-core
#asp.net-
core
Table des matières
À propos 1
Remarques 2
Versions 2
Examples 2
Installation et configuration 2
Contrôleurs 6
Conclusion 7
Utilisation du code Visual Studio pour développer une application core aspnet cross platef 7
Examples 16
Examples 19
Tutoriel rapide pour un Angular 2 Hello World! App avec .Net Core dans Visual Studio 2015 19
Erreurs attendues lors de la génération de composants Angular 2 dans le projet .NET Core ( 44
Introduction 46
Remarques 46
Examples 46
Logger Middleware 46
Chapitre 5: Autorisation 49
Examples 49
Autorisation simple 49
Chapitre 6: Configuration 51
Introduction 51
Syntaxe 51
Examples 51
Commencer 51
Examples 54
Remarques 59
Examples 59
Examples 62
Examples 64
Utiliser NLog Logger 64
Chapitre 11: Envoi d'e-mails dans les applications .Net Core à l'aide de MailKit 66
Introduction 66
Examples 66
Introduction 68
Syntaxe 68
Remarques 68
Examples 69
Contrôle à vie 70
Dépendances énumérables 70
Dépendances génériques 70
Remarques 73
IServiceCollection 76
IServiceProvider 76
Résultat 77
Syntaxe 78
Examples 78
La directive @inject 78
Exemple d'utilisation 78
Configuration requise 78
Examples 79
Examples 81
Routage de base 81
Contraintes de routage 81
Remarques 83
Examples 83
Installer 83
Comportement 87
Installer 89
Comportement 92
Examples 95
Remarques 106
Examples 106
Utilisation du middleware ExceptionHandler pour envoyer une erreur JSON personnalisée au c 106
Introduction 110
Examples 110
Introduction 112
Examples 112
Examples 116
Examples 118
Introduction 124
Examples 124
Paramètres 126
Examples 126
Introduction 133
Examples 133
NuGet 133
npm 133
Configuration 133
Génération d'un exemple d'application d'une page avec asp.net core 134
Crédits 136
À propos
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: asp-net-core
It is an unofficial and free asp.net-core ebook created for educational purposes. All the content is
extracted from Stack Overflow Documentation, which is written by many hardworking individuals at
Stack Overflow. It is neither affiliated with Stack Overflow nor official asp.net-core.
The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.
Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to info@zzzprojects.com
https://riptutorial.com/fr/home 1
Chapitre 1: Démarrer avec asp.net-core
Remarques
.NET Core est une plate-forme de développement à usage général gérée par Microsoft et la
communauté .NET sur GitHub. Il est multi-plateforme, prend en charge Windows, macOS et Linux
et peut être utilisé dans des scénarios de périphériques, de cloud et intégrés / IoT.
• Déploiement flexible: peut être inclus dans votre application ou installé côte à côte à l'échelle
de l'utilisateur ou de la machine.
• Multiplate-forme: s'exécute sur Windows, macOS et Linux; peut être porté sur d'autres
systèmes d'exploitation. Les systèmes d'exploitation, les processeurs et les scénarios
d'application pris en charge évolueront avec le temps, fournis par Microsoft, d'autres
sociétés et des particuliers.
• Outils de ligne de commande: tous les scénarios de produit peuvent être exercés sur la ligne
de commande.
• Compatible: .NET Core est compatible avec .NET Framework, Xamarin et Mono, via la
bibliothèque standard .NET.
• Open source: la plate-forme .NET Core est open source et utilise les licences MIT et Apache
2. La documentation est sous licence CC-BY. .NET Core est un projet .NET Foundation.
• Pris en charge par Microsoft: .NET Core est pris en charge par Microsoft, par le biais du
support .NET Core
Versions
Examples
Installation et configuration
https://riptutorial.com/fr/home 2
Si Visual Studio n'est pas installé, vous pouvez télécharger gratuitement Visual Studio Community
Edition ici . Si vous l'avez déjà installé, vous pouvez passer à l'étape suivante.
Une autre boîte de dialogue vous sera proposée pour sélectionner le modèle que vous souhaitez
utiliser pour le projet:
https://riptutorial.com/fr/home 3
Chacune des descriptions est explicite. Pour ce premier projet, sélectionnez Application Web ,
qui contiendra toutes les configurations par défaut, l'authentification et certains contenus existants.
Appuyez sur la touche F5 pour exécuter l'application et lancer une session de débogage, qui
lancera l'application dans votre navigateur par défaut:
https://riptutorial.com/fr/home 4
Vous pouvez maintenant voir que votre projet est opérationnel localement et que vous êtes prêt à
créer votre application.
Il est possible de créer un nouveau projet ASP.NET Core entièrement à partir de la ligne de
commande en utilisant la commande dotnet .
dotnet new web un nouveau projet web "vide". Le paramètre web indique à l'outil dotnet d'utiliser le
modèle ASP.NET Core Empty . Utilisez dotnet new -all pour afficher tous les modèles disponibles
actuellement installés. Les autres modèles de clé incluent console , classlib , mvc et xunit .
Une fois que le modèle a été échafaudé, vous pouvez restaurer les packages requis pour
exécuter le projet ( dotnet restore ), puis le compiler et le démarrer ( dotnet run ).
Une fois le projet en cours, il sera disponible sur le port par défaut: http: // localhost: 5000
Avec ASP.NET Core 1.0, le framework MVC et Web API ont été fusionnés en un seul framework
appelé ASP.NET Core MVC. C'est une bonne chose, puisque MVC et Web API partagent de
https://riptutorial.com/fr/home 5
nombreuses fonctionnalités, mais il y avait toujours des différences subtiles et la duplication de
code.
Cependant, le fait de fusionner ces deux éléments dans le cadre du premier a rendu plus difficile
la distinction entre les deux. Par exemple, Microsoft.AspNet.WebApi représente le framework Web
API 5.xx, pas le nouveau. Mais lorsque vous incluez Microsoft.AspNetCore.Mvc (version 1.0.0 ),
vous obtenez le package complet. Cela contiendra toutes les fonctionnalités prêtes à l'emploi
proposées par le framework MVC. Comme le rasoir, les aides de balise et la reliure de modèle.
Lorsque vous souhaitez simplement créer une API Web, nous n’avons pas besoin de toutes ces
fonctionnalités. Alors, comment pouvons-nous construire une API Web minimaliste? La réponse
est: Microsoft.AspNetCore.Mvc.Core . Dans le nouveau monde, MVC est divisé en plusieurs
packages et ce package ne contient que les composants principaux du framework MVC, tels que
le routage et l’autorisation.
Pour cet exemple, nous allons créer une API MVC minimale. Y compris un formateur JSON et
CORS. Créez une application Web ASP.NET Core 1.0 vide et ajoutez ces packages à votre
project.json:
"Microsoft.AspNetCore.Mvc.Core": "1.0.0",
"Microsoft.AspNetCore.Mvc.Cors": "1.0.0",
"Microsoft.AspNetCore.Mvc.Formatters.Json": "1.0.0"
Maintenant, nous pouvons enregistrer MVC en utilisant AddMvcCore() dans la classe de démarrage:
Contrôleurs
L'ancienne API Web est livrée avec sa propre classe de base de contrôleur: ApiController . Dans
le nouveau monde, il n’ya rien de tel, seulement la classe de Controller par défaut.
Malheureusement, cette classe de base est relativement volumineuse et liée à la liaison de
modèle, aux vues et à JSON.NET.
https://riptutorial.com/fr/home 6
Heureusement, dans le nouveau framework, les classes de contrôleur n'ont pas à dériver de
Controller pour être captées par le mécanisme de routage. Il suffit d'ajouter le nom avec
Controller . Cela nous permet de construire notre propre classe de base de contrôleur. Appelons
cela ApiController , juste pour le bon vieux temps:
/// <summary>
/// Base class for an API controller.
/// </summary>
[Controller]
public abstract class ApiController
{
[ActionContext]
public ActionContext ActionContext { get; set; }
L'attribut [Controller] indique que le type ou tout type dérivé est considéré comme un contrôleur
par le mécanisme de découverte de contrôleur par défaut. L'attribut [ActionContext] spécifie que la
propriété doit être définie avec le paramètre ActionContext actuel lorsque MVC crée le contrôleur.
ActionContext fournit des informations sur la requête en cours.
ASP.NET Core MVC offre également une classe ControllerBase qui fournit une classe
de base de contrôleur sans support de vues. C'est quand même beaucoup plus grand
que le nôtre. Utilisez-le si vous le trouvez pratique.
Conclusion
Nous pouvons maintenant construire une API Web minimale en utilisant le nouveau framework
ASP.NET Core MVC. La structure modulaire du package nous permet de récupérer les packages
dont nous avons besoin et de créer une application simple et simple.
Utilisation du code Visual Studio pour développer une application core aspnet
cross plateforme
Avec AspNetCore, vous pouvez développer l'application sur n'importe quelle plate-forme, y
compris Mac, Linux, Window et Docker.
Installation et configuration
Vous avez maintenant tous les outils disponibles. Développer l'application Maintenant, vous avez
https://riptutorial.com/fr/home 7
besoin d'une option d'échafaudage. Pour cela, vous devriez envisager d'utiliser Yeoman. Pour
installer Yeoman
1. Installez NPM. Pour cela, vous avez besoin d'un nœud sur votre machine. Installer à partir d'
ici
npm install -g yo
Maintenant, nous avons toute la configuration sur votre machine. Commençons par créer un
nouveau projet avec la commande de base DotNetCore et ensuite créer un nouveau projet en
utilisant Yo.
2. Echafaudage d'un projet dotnet très basique en utilisant l'option de ligne de commande par
défaut
dotnet Nouveau
https://riptutorial.com/fr/home 8
Utilisez Yeoman comme option d'échafaudage
yo aspnet
Yeoman demandera des entrées comme Type de projet, Nom du projet, etc.
https://riptutorial.com/fr/home 9
Maintenant, restaurez les paquets en exécutant la commande dotnet restore et exécutez
l'application
https://riptutorial.com/fr/home 10
Ouvrez maintenant les fichiers et exécutez l'application. Vous pouvez également rechercher
l'extension pour votre aide.
https://riptutorial.com/fr/home 11
l'environnement actuel. Par défaut, si vous exécutez votre application sans définir cette valeur,
elle sera automatiquement utilisée par défaut dans l'environnement de Production .
Vous pouvez facilement définir une variable d'environnement à partir d'une invite de commandes
à l'aide de la commande setx.exe incluse dans Windows. Vous pouvez l'utiliser pour définir
facilement une variable utilisateur:
Notez que la variable d'environnement n'est pas définie dans la fenêtre ouverte en cours. Vous
devrez ouvrir une nouvelle invite de commande pour voir l'environnement mis à jour. Il est
également possible de définir des variables système (plutôt que des variables utilisateur) si vous
ouvrez une invite de commande administrative et ajoutez le commutateur / M:
Utilisation de PowerShell Vous pouvez également utiliser PowerShell pour définir la variable.
Dans PowerShell, ainsi que les variables utilisateur et système normales, vous pouvez également
créer une variable temporaire à l'aide de la commande $Env: :
$Env:ASPNETCORE_ENVIRONMENT = "Development"
La variable créée ne dure que pendant la durée de votre session PowerShell. Une fois la fenêtre
fermée, l'environnement revient à sa valeur par défaut.
Vous pouvez également définir directement les variables d'environnement utilisateur ou système.
Cette méthode ne modifie pas les variables d'environnement dans la session en cours. Vous
devrez donc ouvrir une nouvelle fenêtre PowerShell pour voir vos modifications. Comme
précédemment, la modification des variables système (machine) nécessitera un accès
administratif
https://riptutorial.com/fr/home 12
Utilisation du panneau de configuration Windows Si vous n'êtes pas fan de l'invite de
commande, vous pouvez facilement mettre à jour vos variables avec la souris! Cliquez sur le
bouton Démarrer de Windows (ou appuyez sur la touche Windows), recherchez environment
variables environnement variables pour votre compte:
https://riptutorial.com/fr/home 13
Cliquez sur Variables d'environnement pour afficher la liste des variables d'environnement
actuelles sur votre système.
https://riptutorial.com/fr/home 14
En supposant que vous ne possédez pas déjà une variable appelée ASPNETCORE_ENVIRONMENT ,
cliquez sur le bouton Nouveau ... et ajoutez une nouvelle variable d'environnement de compte:
Cliquez sur OK pour enregistrer toutes vos modifications. Vous devrez rouvrir toutes les fenêtres
de commande pour vous assurer que les nouvelles variables d'environnement sont chargées.
https://riptutorial.com/fr/home 15
Chapitre 2: Afficher les composants
Examples
Créer un composant de vue
Les composants de vue encapsulent des éléments de logique et des vues réutilisables. Ils sont
définis par:
Comme ils contiennent une logique, ils sont plus flexibles que les vues partielles tout en favorisant
une bonne séparation des préoccupations.
//renders ~/Views/Shared/Components/MyCustom/Default.cshtml
return View(new MyCustomModel{ ... });
}
}
Ils peuvent être appelés depuis n'importe quelle vue (ou même un contrôleur en retournant un
ViewComponentResult )
Le modèle de projet par défaut crée une vue partielle _LoginPartial.cshtml qui contient un peu
de logique pour savoir si l'utilisateur est connecté ou non et trouver son nom d'utilisateur.
Comme un composant de vue peut convenir mieux (car il y a une logique impliquée et même 2
services injectés), l'exemple suivant montre comment convertir le LoginPartial en un composant
de vue.
https://riptutorial.com/fr/home 16
public class LoginViewComponent : ViewComponent
{
private readonly SignInManager<ApplicationUser> signInManager;
private readonly UserManager<ApplicationUser> userManager;
@model WebApplication1.Models.ApplicationUser
@await Component.InvokeAsync("Login")
Lorsque vous héritez de la classe Controller de base fournie par la structure, vous pouvez utiliser
la méthode ViewComponent() pour renvoyer un composant de vue à partir de l'action:
https://riptutorial.com/fr/home 17
public IActionResult GetMyComponent()
{
return ViewComponent("Login", new { param1 = "foo", param2 = 42 });
}
Si vous utilisez une classe POCO en tant que contrôleur, vous pouvez créer manuellement une
instance de la classe ViewComponentResult . Ce serait équivalent au code ci-dessus:
https://riptutorial.com/fr/home 18
Chapitre 3: Angular2 et .Net Core
Examples
Tutoriel rapide pour un Angular 2 Hello World! App avec .Net Core dans
Visual Studio 2015
Pas:
https://riptutorial.com/fr/home 19
2. Allez sur wwwroot et créez une page HTML normale appelée Index.html:
https://riptutorial.com/fr/home 20
3. Configurez Startup.cs pour accepter les fichiers statiques (ceci nécessitera d'ajouter la
bibliothèque "Microsoft.AspNetCore.StaticFiles": "1.0.0" dans le fichier "project.json"):
https://riptutorial.com/fr/home 21
4. Ajouter un fichier NPN:
• Cliquez avec le bouton droit sur le projet WebUi et ajoutez le fichier de configuration
NPN (package.json):
https://riptutorial.com/fr/home 22
• Vérifiez les dernières versions des packages:
https://riptutorial.com/fr/home 23
Remarque: Si Visual Studio ne détecte pas les versions des packages (vérifiez tous les
packages, car certains d’entre eux affichent la version, et d’autres non), cela peut être
dû au fait que la version Node fournie par Visual Studio ne fonctionne pas
correctement , il faudra donc probablement installer le noeud js en externe et lier cette
installation à Visual Studio.
https://riptutorial.com/fr/home 24
iii. (Facultatif) Après avoir enregistré le package.json, il installera les dépendances
dans le projet, sinon, exécutez "npm install" en utilisant une invite de commande du
même emplacement que le fichier package.json.
https://riptutorial.com/fr/home 25
Remarque: Recommandé pour installer "Open Command Line", une extension qui peut
être ajoutée à Visual Studio:
• Créez un dossier TsScript dans le projet WebUi, juste pour l’organisation (les scripts
TypeScripts ne seront pas envoyés au navigateur, ils seront transposés dans un fichier
JS normal, et ce fichier JS sera celui qui va au générateur wwwroot en utilisant gulp,
ceci sera expliqué plus tard):
https://riptutorial.com/fr/home 26
• Dans ce dossier, ajoutez "Fichier de configuration JSON TypeScript" (tsconfig.json):
https://riptutorial.com/fr/home 27
Et ajoutez le code suivant:
https://riptutorial.com/fr/home 28
• Dans la racine du projet WebUi, ajoutez un nouveau fichier appelé typings.json:
https://riptutorial.com/fr/home 29
Et ajoutez le code suivant:
https://riptutorial.com/fr/home 30
• Dans la racine du projet Web, ouvrez une ligne de commande et exécutez «typings
install», cela créera un dossier de saisie (Cela nécessite «Ouvrir une ligne de
commande» expliquée comme une étape facultative dans la note de l'étape 4, chiffre
iii).
https://riptutorial.com/fr/home 31
https://riptutorial.com/fr/home 32
https://riptutorial.com/fr/home 33
6. Ajoutez gulp pour déplacer les fichiers:
https://riptutorial.com/fr/home 34
• Ajouter un code:
https://riptutorial.com/fr/home 35
7. Ajoutez les fichiers d'amorçage Angular 2 dans le dossier «tsScripts»:
https://riptutorial.com/fr/home 36
app.component.ts
https://riptutorial.com/fr/home 37
app.module.ts
main.ts
https://riptutorial.com/fr/home 38
Et ajoutez le code suivant:
https://riptutorial.com/fr/home 39
10. Exécutez la tâche Gulp pour générer les scripts dans wwwroot.
https://riptutorial.com/fr/home 40
je. Si les tâches ne sont pas chargées ("Echec du chargement. Voir Fenêtre de sortie")
Allez dans la fenêtre de sortie et examinez les erreurs, la plupart du temps des erreurs
de syntaxe dans le fichier gulp.
• Clic droit sur la tâche "par défaut" et "Exécuter" (cela prendra du temps, et les
messages de confirmation ne sont pas très précis, cela montre que c'est fini mais le
processus est toujours en cours, gardez cela à l'esprit):
https://riptutorial.com/fr/home 41
11. Modifier Index.html comme:
https://riptutorial.com/fr/home 42
12. Maintenant courez et appréciez.
Remarques:
• S'il existe des erreurs de compilation avec typecript, par exemple "TypeScript Virtual
Project", cela indique que la version de TypeScript pour Visual Studio n'est pas mise à
jour en fonction de la version sélectionnée dans le fichier "package.json". :
https://www.microsoft.com/en-us/download/details.aspx?id=48593
Les références:
https://riptutorial.com/fr/home 43
• Le cours "Angular 2: Getting Started" de Deborah Kurata à Pluralsight:
https://www.pluralsight.com/courses/angulaire-2-getting-started-update
https://angular.io/
http://www.mithunvp.com/angular-2-in-asp-net-5-typescript-visual-studio-2015/
http://www.mithunvp.com/using-angular-2-asp-net-mvc-5-visual-studio/
Lors de la génération de nouveaux composants Angular 2 dans un projet .NET Core, vous pouvez
rencontrer les erreurs suivantes (à partir de la version 0.8.3):
OU
No app module found. Please add your new Class to your component.
Identical ClientApp/app/app.module.ts
[SOLUTION]
3. Ouvrez boot-client.ts: mettez à jour votre importation pour utiliser la nouvelle référence
app.client.module.
[EXPLICATION]
CLI angulaire recherche un fichier nommé app.module.ts dans votre projet et tente de trouver une
référence à la propriété declarations pour importer le composant. Cela devrait être un tableau
(comme le partage SharedConfig.declarations), mais les modifications ne sont pas appliquées
https://riptutorial.com/fr/home 44
[SOURCES]
• https://github.com/angular/angular-cli/issues/2962
• https://www.udemy.com/aspnet-core-angular/learn/v4/t/lecture/6848548 (Bryan Garzon,
collaborateur de la section 3.33)
https://riptutorial.com/fr/home 45
Chapitre 4: ASP.NET Core - Journal à la fois
de la demande et de la réponse à l'aide de
middleware
Introduction
Pendant un certain temps, j'ai cherché le meilleur moyen de consigner les demandes et les
réponses dans un noyau ASP.Net. Je développais des services et l'une des exigences était
d'enregistrer la demande avec sa réponse dans un enregistrement de la base de données. Tant
de sujets là-bas mais aucun n'a fonctionné pour moi. c'est soit pour la demande seulement, la
réponse seulement ou tout simplement n'a pas fonctionné. Lorsque j'ai pu enfin le faire, et au
cours de mon projet, il a évolué pour mieux gérer les erreurs et enregistrer les exceptions, j'ai
donc pensé au partage.
Remarques
certains des sujets qui m'ont aidé:
• http://www.sulhome.com/blog/10/log-asp-net-core-request-and-response-using-middleware
• http://dotnetliberty.com/index.php/2016/01/07/logging-asp-net-5-requests-using-middleware/
• Comment connecter le corps de réponse HTTP dans ASP.NET Core 1.0
Examples
Logger Middleware
using Microsoft.AspNetCore.Http;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Http.Internal;
using Microsoft.AspNetCore.Http.Internal;
https://riptutorial.com/fr/home 46
{
using (MemoryStream responseBodyStream = new MemoryStream())
{
Stream originalRequestBody = context.Request.Body;
context.Request.EnableRewind();
Stream originalResponseBody = context.Response.Body;
try
{
await context.Request.Body.CopyToAsync(requestBodyStream);
requestBodyStream.Seek(0, SeekOrigin.Begin);
requestBodyStream.Seek(0, SeekOrigin.Begin);
context.Request.Body = requestBodyStream;
context.Response.Body = responseBodyStream;
responseBodyStream.Seek(0, SeekOrigin.Begin);
responseBody = new StreamReader(responseBodyStream).ReadToEnd();
AuditLogger.LogToAudit(context.Request.Host.Host,
context.Request.Path, context.Request.QueryString.ToString(),
context.Connection.RemoteIpAddress.MapToIPv4().ToString(),
string.Join(",", context.Request.Headers.Select(he => he.Key +
":[" + he.Value + "]").ToList()),
requestBodyText, responseBody, DateTime.Now,
watch.ElapsedMilliseconds);
responseBodyStream.Seek(0, SeekOrigin.Begin);
await responseBodyStream.CopyToAsync(originalResponseBody);
}
catch (Exception ex)
{
ExceptionLogger.LogToDatabse(ex);
byte[] data = System.Text.Encoding.UTF8.GetBytes("Unhandled Error
occured, the error has been logged and the persons concerned are notified!! Please, try again
in a while.");
originalResponseBody.Write(data, 0, data.Length);
}
finally
{
context.Request.Body = originalRequestBody;
context.Response.Body = originalResponseBody;
}
}
}
}
}
https://riptutorial.com/fr/home 47
ligne: https://riptutorial.com/fr/asp-net-core/topic/9510/asp-net-core---journal-a-la-fois-de-la-
demande-et-de-la-reponse-a-l-aide-de-middleware
https://riptutorial.com/fr/home 48
Chapitre 5: Autorisation
Examples
Autorisation simple
[Authorize]
public class SomeController : Controller
{
public IActionResult Get()
{
}
[Authorize]
public IActionResult Post()
{
}
}
Si vous souhaitez autoriser tous les utilisateurs à accéder à l'une des actions, vous pouvez utiliser
AllowAnonymousAttribute
[Authorize]
public class SomeController: Controller
{
public IActionResult Get()
{
}
[AllowAnonymous]
public IActionResult Post()
{
}
}
Maintenant, n'importe quel utilisateur peut accéder à Post . AllowAnonymous toujours une priorité à
https://riptutorial.com/fr/home 49
autoriser, donc si un contrôleur est défini sur AllowAnonymous toutes ses actions sont publiques,
qu'elles aient ou non un AuthorizeAttribute .
Il existe une option permettant de configurer tous les contrôleurs pour exiger des requêtes
autorisées -
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
})
Cela se fait en ajoutant une stratégie d'autorisation par défaut à chaque contrôleur - tout attribut
Authorize / AllowAnonymous sur un contrôleur / action remplacera ces paramètres.
https://riptutorial.com/fr/home 50
Chapitre 6: Configuration
Introduction
Le noyau Asp.net fournit des abstractions de configuration. Ils vous permettent de charger les
paramètres de configuration à partir de différentes sources et de créer un modèle de configuration
final qui peut ensuite être utilisé par votre application.
Syntaxe
• IConfiguration
• string this[string key] { get; set; }
• IEnumerable<IConfigurationSection> GetChildren();
• IConfigurationSection GetSection(string key);
Examples
Accès à la configuration en utilisant l'injection de dépendance
Cela dit, cela reste assez simple pour rendre IConfigurationRoot disponible à l’échelle des
applications.
Dans le constructeur Startup.cs, vous devez avoir le code suivant pour générer la configuration,
Configuration = builder.Build();
Ici, la Configuration est une instance de IConfigurationRoot , et ajoute cette instance en tant que
Singleton à la collection de services dans la méthode ConfigureServices, Startup.cs,
Par exemple, vous pouvez maintenant accéder à la configuration dans un contrôleur / service
Commencer
Dans cet exemple, nous allons décrire ce qui se passe lorsque vous échafaudez un nouveau
projet.
https://riptutorial.com/fr/home 51
Tout d'abord, les dépendances suivantes seront ajoutées à votre projet (actuellement fichier
project.json ):
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
Il va également créer un constructeur dans votre fichier Startup.cs qui sera chargé de construire la
configuration à l'aide d'Api ConfigurationBuilder fluent:
Configuration = builder.Build();
}
Si un même paramètre est défini dans plusieurs sources, la dernière source ajoutée gagnera et sa
valeur sera sélectionnée.
La configuration peut ensuite être consommée à l'aide de la propriété de l'indexeur. Les deux
points : caractère servent un délimiteur de chemin.
Configuration["AzureLogger:ConnectionString"]
Cela recherchera une valeur de configuration ConnectionString dans une section AzureLogger .
Il chargera les variables d'environnement préfixées par APPSETTING_ Il utilisera alors deux points :
comme séparateur de chemin de clé.
APPSETTING_Security:Authentication:UserName = a_user_name
https://riptutorial.com/fr/home 52
APPSETTING_Security:Authentication:Password = a_user_password
{
"Security" : {
"Authentication" : {
"UserName" : "a_user_name",
"Password" : "a_user_password"
}
}
}
** Notez que Azure Service transmettra les paramètres en tant que variables d'environnement. Le
préfixe sera défini pour vous de manière transparente. Donc, pour faire la même chose dans
Azure, il suffit de définir deux paramètres d'application dans la lame AppSettings:
Security:Authentication:UserName a_user_name
Security:Authentication:Password a_user_password
Lorsque vous traitez de grands ensembles de valeurs de configuration, il peut être difficile de les
charger en un seul.
Modèle d'option qui vient avec asp.net offre un moyen pratique pour mapper une section à une
dotnet poco : Par exemple, on peut hydrater StorageOptions directement à partir d' une section de
configuration b ajoutant Microsoft.Extensions.Options.ConfigurationExtensions package et en
appelant le Configure<TOptions>(IConfiguration config) méthode d'extension.
services.Configure<StorageOptions>(Configuration.GetSection("Storage"));
Vous pouvez également créer une configuration à partir d'un objet en mémoire tel qu'un
Dictionary<string,string>
Cela peut s'avérer utile dans les scénarios de test d'intégration / d'unité.
https://riptutorial.com/fr/home 53
Chapitre 7: Configuration de plusieurs
environnements
Examples
Avoir des appsettings par environnement
Pour chaque environnement, vous devez créer un fichier appsettings distinct. {EnvironmentName}
.json:
• appsettings.Development.json
• appsettings.Staging.json
• appsettings.Production.json
"publishOptions": {
"include": [
"appsettings.Development.json",
"appsettings.Staging.json",
"appsettings.Production.json"
...
]
}
Tout ce dont vous avez besoin est une variable de type IHostingEnvironment :
env.EnvironmentName
https://riptutorial.com/fr/home 54
• Prédéfini Development , Staging en Production Staging , Production des environnements est la
meilleure façon d'utiliser des méthodes d'extension de HostingEnvironmentExtensions
classe
env.IsDevelopment()
env.IsStaging()
env.IsProduction()
env.IsEnvironment("environmentname")
env.EnvironmentName == "Development"
Cet exemple montre comment configurer plusieurs environnements avec une configuration
d'injection de dépendances différente et des middlewares distincts dans une classe de Startup .
L'utilisation de ce modèle évite de mettre beaucoup de logique if/else une seule méthode / classe
de Startup et de la garder propre et séparée.
Un exemple complet:
https://riptutorial.com/fr/home 55
{
public Startup(IHostingEnvironment hostEnv)
{
// Set up configuration sources.
var builder = new ConfigurationBuilder()
.SetBasePath(hostEnv.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{hostEnv.EnvironmentName}.json", optional: true,
reloadOnChange: true);
if (hostEnv.IsDevelopment())
{
// This will push telemetry data through Application Insights pipeline faster,
allowing you to view results immediately.
builder.AddApplicationInsightsSettings(developerMode: true);
}
builder.AddEnvironmentVariables();
Configuration = builder.Build();
}
// This method gets called by the runtime. Use this method to add services to the
container
public static void RegisterCommonServices(IServiceCollection services)
{
services.AddScoped<ICommonService, CommonService>();
services.AddScoped<ICommonRepository, CommonRepository>();
}
services.AddOptions();
services.AddMvc();
}
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
app.UseApplicationInsightsRequestTelemetry();
app.UseApplicationInsightsExceptionTelemetry();
app.UseStaticFiles();
app.UseMvc();
}
app.UseApplicationInsightsRequestTelemetry();
https://riptutorial.com/fr/home 56
app.UseApplicationInsightsExceptionTelemetry();
app.UseStaticFiles();
app.UseMvc();
}
}
Il se peut que vous deviez afficher du contenu dans une vue spécifique à un environnement
uniquement. Pour atteindre cet objectif, vous pouvez utiliser l' assistant de balise Environment:
<environment names="Development">
<h1>This is heading for development environment</h1>
</environment>
<environment names="Staging,Production">
<h1>This is heading for Staging or production environment</h1>
</environment>
SET ASPNETCORE_ENVIRONMENT=Development
L'exécution d'une application Asp.Net Core se fera désormais dans l'environnement défini.
Remarque
Lorsque vous utilisez PowerShell, vous pouvez utiliser setx.exe pour définir les variables
d'environnement de manière permanente.
1. Démarrer PowerShell
3. Redémarrer PowerShell
https://riptutorial.com/fr/home 57
Si vous ne souhaitez pas utiliser ASPNETCORE_ENVIRONMENT à partir de variables
d'environnement et l'utiliser depuis web.config de votre application, modifiez le fichier web.config
comme ceci -
https://riptutorial.com/fr/home 58
Chapitre 8: Demandes d'origine croisée
(CORS)
Remarques
La sécurité du navigateur empêche une page Web de faire des requêtes AJAX vers un autre
domaine. Cette restriction s'appelle la politique de même origine et empêche un site malveillant de
lire des données sensibles d'un autre site. Cependant, il peut arriver que vous souhaitiez laisser
d’autres sites créer des requêtes d’origine croisée vers votre application Web.
Cross Origin Resource Sharing (CORS) est un standard W3C qui permet à un serveur d'assouplir
la politique de même origine. En utilisant CORS, un serveur peut autoriser explicitement certaines
requêtes d’origine croisée tout en en rejetant d’autres. CORS est plus sûr et plus flexible que les
techniques antérieures telles que JSONP.
Examples
Activer CORS pour toutes les demandes
Utilisez la méthode d'extension UseCors() sur IApplicationBuilder dans la méthode Configure pour
appliquer la stratégie CORS à toutes les demandes.
app.UseCors(builder =>
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
// Other middleware..
app.UseMvc();
}
Pour activer une stratégie CORS pour des contrôleurs spécifiques, vous devez créer la stratégie
dans l'extension AddCors dans la méthode ConfigureServices :
https://riptutorial.com/fr/home 59
services.AddCors(cors => cors.AddPolicy("AllowAll", policy =>
{
policy.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
[EnableCors("AllowAll")]
public class HomeController : Controller
{
// ...
}
app.UseCors(builder =>
{
builder.WithOrigins("http://localhost:5000", "http://myproductionapp.com")
.WithMethods("GET", "POST", "HEAD")
.WithHeaders("accept", "content-type", "origin")
.SetPreflightMaxAge(TimeSpan.FromDays(7));
});
Pour activer une stratégie CORS sur tous vos contrôleurs MVC, vous devez créer la stratégie
dans l'extension AddCors dans la méthode ConfigureServices, puis définir la stratégie sur
CorsAuthorizationFilterFactory
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Cors.Internal;
...
public void ConfigureServices(IServiceCollection services) {
// Add AllowAll policy just like in single controller example.
services.AddCors(options => {
options.AddPolicy("AllowAll",
builder => {
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
https://riptutorial.com/fr/home 60
services.AddMvc();
services.Configure<MvcOptions>(options => {
options.Filters.Add(new CorsAuthorizationFilterFactory("AllowAll"));
});
}
Cette stratégie CORS peut être remplacée sur une base de contrôleur ou d'action, mais cela peut
définir la valeur par défaut pour toute l'application.
https://riptutorial.com/fr/home 61
Chapitre 9: Des modèles
Examples
Validation de modèles avec attributions de validation
Les attributs de validation peuvent être utilisés pour configurer facilement la validation du modèle.
Si les attributs intégrés ne sont pas suffisants pour valider les données de votre modèle, vous
pouvez placer votre logique de validation dans une classe dérivée de ValidationAttribute. Dans cet
exemple, seuls les nombres impairs sont des valeurs valides pour un membre du modèle.
https://riptutorial.com/fr/home 62
return ValidationResult.Success;
else
return new ValidationResult("Only odd numbers are valid.");
}
catch (Exception)
{
return new ValidationResult("Not a number.");
}
}
}
Classe de modèle
https://riptutorial.com/fr/home 63
Chapitre 10: Enregistrement
Examples
Utiliser NLog Logger
NLog.Extensions.Logging est le fournisseur officiel NLog pour Microsoft dans .NET Core et
ASP.NET Core. Ici et ici sont des instructions et des exemples respectivement.
"Serilog": "2.2.0",
"Serilog.Extensions.Logging": "1.2.0",
"Serilog.Sinks.RollingFile": "2.0.0",
"Serilog.Sinks.File": "3.0.0"
loggerFactory.AddSerilog();
https://riptutorial.com/fr/home 64
ILogger<HomeController> _logger = null;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
try
{
throw new Exception("Serilog Testing");
}
catch (System.Exception ex)
{
this._logger.LogError(ex.Message);
}
https://riptutorial.com/fr/home 65
Chapitre 11: Envoi d'e-mails dans les
applications .Net Core à l'aide de MailKit
Introduction
Actuellement, .Net Core n'inclut pas le support pour envoyer des emails comme System.Net.Mail
de .Net. Le projet MailKit (disponible sur nuget ) est une bibliothèque intéressante à cet effet.
Examples
Installation du paquet nuget
Install-Package MailKit
using MailKit.Net.Smtp;
using MimeKit;
using MimeKit.Text;
using System.Threading.Tasks;
namespace Project.Services
{
/// Using a static class to store sensitive credentials
/// for simplicity. Ideally these should be stored in
/// configuration files
public static class Constants
{
public static string SenderName => "<sender_name>";
public static string SenderEmail => "<sender_email>";
public static string EmailPassword => "email_password";
public static string SmtpHost => "<smtp_host>";
public static int SmtpPort => "smtp_port";
}
public class EmailService : IEmailSender
{
public Task SendEmailAsync(string recipientEmail, string subject, string message)
{
MimeMessage mimeMessage = new MimeMessage();
mimeMessage.From.Add(new MailboxAddress(Constants.SenderName,
Constants.SenderEmail));
mimeMessage.To.Add(new MailboxAddress("", recipientEmail));
mimeMessage.Subject = subject;
https://riptutorial.com/fr/home 66
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
client.AuthenticationMechanisms.Remove("XOAUTH2");
client.Send(mimeMessage);
client.Disconnect(true);
return Task.FromResult(0);
}
}
}
Lire Envoi d'e-mails dans les applications .Net Core à l'aide de MailKit en ligne:
https://riptutorial.com/fr/asp-net-core/topic/8831/envoi-d-e-mails-dans-les-applications--net-core-a-
l-aide-de-mailkit
https://riptutorial.com/fr/home 67
Chapitre 12: Injection de dépendance
Introduction
Le noyau Aspnet est construit avec l'injection de dépendance comme l'un de ses concepts clés. Il
introduit une abstraction de conteneur conforme afin que vous puissiez remplacer celle intégrée
par un conteneur tiers de votre choix.
Syntaxe
• IServiceCollection.Add(ServiceDescriptor item);
• IServiceCollection.AddScoped(Type serviceType);
• IServiceCollection.AddScoped(Type serviceType, Type implementationType);
• IServiceCollection.AddScoped(Type serviceType, Func<IServiceProvider, object>
implementationFactory);
• IServiceCollection.AddScoped<TService>()
• IServiceCollection.AddScoped<TService>(Func<IServiceProvider, TService>
implementationFactory)
• IServiceCollection.AddScoped<TService, TImplementation>()
• IServiceCollection.AddScoped<TService, TImplementation>(Func<IServiceProvider,
TImplementation> implementationFactory)
• IServiceCollection.AddSingleton(Type serviceType);
• IServiceCollection.AddSingleton(Type serviceType, Func<IServiceProvider, object>
implementationFactory);
• IServiceCollection.AddSingleton(Type serviceType, Type implementationType);
• IServiceCollection.AddSingleton(Type serviceType, object implementationInstance);
• IServiceCollection.AddSingleton<TService>()
• IServiceCollection.AddSingleton<TService>(Func<IServiceProvider, TService>
implementationFactory)
• IServiceCollection.AddSingleton<TService>(TService implementationInstance)
• IServiceCollection.AddSingleton<TService, TImplementation>()
• IServiceCollection.AddSingleton<TService, TImplementation>(Func<IServiceProvider,
TImplementation> implementationFactory)
• IServiceCollection.AddTransient(Type serviceType);
• IServiceCollection.AddTransient(Type serviceType, Func<IServiceProvider, object>
implementationFactory);
• IServiceCollection.AddTransient(Type serviceType, Type implementationType);
• IServiceCollection.AddTransient<TService>()
• IServiceCollection.AddTransient<TService>(Func<IServiceProvider, TService>
implementationFactory)
• IServiceCollection.AddTransient<TService, TImplementation>()
• IServiceCollection.AddTransient<TService, TImplementation>(Func<IServiceProvider,
TImplementation> implementationFactory)
• IServiceProvider.GetService(Type serviceType)
• IServiceProvider.GetService<T>()
• IServiceProvider.GetServices(Type serviceType)
• IServiceProvider.GetServices<T>()
Remarques
Pour utiliser des variantes génériques de méthodes IServiceProvider , vous devez inclure l'espace
de noms suivant:
https://riptutorial.com/fr/home 68
using Microsoft.Extensions.DependencyInjection;
Examples
Enregistrez et résolvez manuellement
La méthode privilégiée pour décrire les dépendances consiste à utiliser l’injection de constructeur
qui suit le principe de dépendances explicites :
ITestService.cs
TestService.cs
Startup.cs (ConfigureServices)
services.AddTransient<ITestService, TestService>();
}
HomeController.cs
using Microsoft.Extensions.DependencyInjection;
namespace Core.Controllers
{
public class HomeController : Controller
{
public HomeController(ITestService service)
{
int rnd = service.GenerateRandom();
}
}
}
https://riptutorial.com/fr/home 69
Le conteneur intégré est livré avec un ensemble de fonctionnalités intégrées:
Contrôle à vie
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddTransient<ITestService, TestService>();
// or
services.AddScoped<ITestService, TestService>();
// or
services.AddSingleton<ITestService, TestService>();
// or
services.AddSingleton<ITestService>(new TestService());
}
Dépendances énumérables
Il est également possible d'enregistrer des dépendances énumérables:
services.TryAddEnumerable(ServiceDescriptor.Transient<ITestService, TestServiceImpl1>());
services.TryAddEnumerable(ServiceDescriptor.Transient<ITestService, TestServiceImpl2>());
Dépendances génériques
Vous pouvez également enregistrer des dépendances génériques:
services.Add(ServiceDescriptor.Singleton(typeof(IKeyValueStore<>), typeof(KeyValueStore<>)));
https://riptutorial.com/fr/home 70
public class HomeController : Controller
{
public HomeController(IKeyValueStore<UserSettings> userSettings)
{
// do something with services.
}
}
Une fois enregistrée, une dépendance peut être extraite en ajoutant des paramètres au
constructeur Controller.
// ...
using System;
using Microsoft.Extensions.DependencyInjection;
namespace Core.Controllers
{
public class HomeController : Controller
{
public HomeController(ITestService service)
{
int rnd = service.GenerateRandom();
}
}
}
Une fonction intégrée moins connue est l’injection d’action de contrôleur à l’aide de
FromServicesAttribute .
[HttpGet]
public async Task<IActionResult> GetAllAsync([FromServices]IProductService products)
{
return Ok(await products.GetAllAsync());
}
Une note importante est que le [FromServices] ne peut pas être utilisé comme mécanisme général
"Injection de propriété" ou "Injection de méthode"! Il ne peut être utilisé que sur les paramètres de
méthode d'une action de contrôleur ou d'un constructeur de contrôleur (dans le constructeur, il est
obsolète, car le système ASP.NET Core DI utilise déjà l'injection de constructeur et aucun
marqueur supplémentaire n'est requis).
Il ne peut être utilisé nulle part en dehors des contrôleurs, action du contrôleur . Il est
également très spécifique à ASP.NET Core MVC et réside dans l'assembly
Microsoft.AspNetCore.Mvc.Core .
Citation originale du problème ASP.NET Core MVC GitHub ( Limiter [FromServices] à appliquer
uniquement aux paramètres ) concernant cet attribut:
https://riptutorial.com/fr/home 71
@rynowak:
@Eilon:
D'accord, nous avons eu un certain nombre de problèmes publiés par les utilisateurs
avec la confusion sur la façon dont cette fonctionnalité doit être utilisée. Il y a vraiment
eu pas mal de commentaires à la fois: "[FromServices] est bizarre et je ne l'aime pas"
et "[FromServices] m'a confondu". On se croirait dans un piège et l'équipe répondrait
encore à des questions dans des années.
Nous pensons que le scénario le plus précieux pour [FromServices] est sur le
paramètre de méthode d'une action pour un service dont vous avez besoin
uniquement à cet endroit.
Remarques:
• Tous les services enregistrés avec le système d'injection de dépendance .NET Core
peuvent être injectés dans l'action d'un contrôleur à l'aide de l'attribut [FromServices] .
• Le cas le plus pertinent est celui où vous avez besoin d'un service uniquement en une seule
méthode et que vous ne voulez pas encombrer le constructeur de votre contrôleur avec une
autre dépendance, qui ne sera utilisée qu'une seule fois.
• Ne peut pas être utilisé en dehors de ASP.NET Core MVC (c'est-à-dire des applications de
console .NET Framework ou .NET Core pures), car il réside dans l'assembly
Microsoft.AspNetCore.Mvc.Core .
• Pour l'injection de propriété ou de méthode, vous devez utiliser l'un des conteneurs IoC tiers
disponibles (Autofac, Unity, etc.).
Avec ASP.NET Core, l’équipe Microsoft a également introduit le modèle Options, qui permet
d’avoir des options typées robustes et une fois configuré la possibilité d’injecter les options dans
vos services.
Nous commençons par une classe typée forte, qui conservera notre configuration.
https://riptutorial.com/fr/home 72
public string Value1 { get; set; }
public string Value2 { get; set; }
}
{
"mysettings" : {
"value1": "Hello",
"value2": "World"
}
}
services.Configure<MySettings>(Configuration.GetSection("mysettings"));
2. Le faire manuellement
services.Configure<MySettings>(new MySettings
{
Value1 = "Hello",
Value2 = Configuration["mysettings:value2"]
});
Chaque niveau hiérarchique du appsettings.json est séparé par un : . Puisque value2 est
une propriété de l'objet mysettings , on y accède via mysettings:value2 .
Enfin, nous pouvons injecter les options dans nos services, en utilisant l’ IOptions<T>
Remarques
Si IOptions<T> n'est pas configuré au démarrage, l'injection d' IOptions<T> injectera l'instance par
défaut de la classe T
https://riptutorial.com/fr/home 73
Résoudre les services de portée au démarrage de l'application peut être difficile, car il n'y a pas de
demande et donc pas de service de portée.
Le modèle suivant résout le problème en créant d'abord une nouvelle étendue, puis en résolvant
les services qui lui sont associés, puis, une fois le travail terminé, en éliminant le conteneur de
portée.
if (await db.Database.EnsureCreatedAsync())
{
await SeedDatabase(db);
}
}
}
Il s’agit d’une manière semi-officielle de l’équipe principale d’Entity Framework d’ensemencer les
données lors du démarrage de l’application et est reflétée dans l’ exemple d’ application
MusicStore .
Par défaut, les contrôleurs, ViewComponents et TagHelpers ne sont pas enregistrés et résolus via
le conteneur d'injection de dépendance. Cela se traduit par l'incapacité de faire, c'est-à-dire
l'injection de propriété lors de l'utilisation d'un conteneur Inversion of Control (IoC) tiers tel
qu'AutoFac.
Pour que les types ASP.NET Core MVC résolvent ces types via IoC, il faut ajouter les
enregistrements suivants dans Startup.cs (extrait de l'exemple officiel ControllersFromService sur
GitHub)
https://riptutorial.com/fr/home 74
{
manager.ApplicationParts.Add(new TypesPart(
typeof(AnotherController),
typeof(ComponentFromServicesViewComponent),
typeof(InServicesTagHelper)));
manager.FeatureProviders.Add(new AssemblyMetadataReferenceFeatureProvider());
})
.AddControllersAsServices()
.AddViewComponentsAsServices()
.AddTagHelpersAsServices();
services.AddTransient<QueryValueService>();
services.AddTransient<ValueService>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
services.AddTransient<ServiceDependingOnIMyInterface>();
var spWithService = services.BuildServiceProvider(); //Generaly its bad practise to
rebuild the container because its heavey and promotes use of anti-pattern.
spWithService.GetService<ServiceDependingOnIMyInterface>(); //only now i can resolve
}
}
interface IMyInterface
{
}
class ServiceDependingOnIMyInterface
{
private readonly IMyInterface _dependency;
https://riptutorial.com/fr/home 75
{
_dependency = dependency;
}
}
IServiceCollection
Pour commencer à créer un conteneur IOC avec le package DI nuget de Microsoft, commencez
par créer un IServiceCollection . Vous pouvez utiliser la collection déjà fournie: ServiceCollection :
Toutes les méthodes suivantes ne sont que des méthodes d'extension permettant d'ajouter des
instances ServiceDescriptor à la liste:
IServiceProvider
Le serviceprovider est celui qui "Compile" tous les enregistrements afin qu'ils puissent être utilisés
rapidement, cela peut être fait avec services.BuildServiceProvider() qui est fondamentalement un
code d'extension pour:
var provider = new ServiceProvider( services, false); //false is if it should validate scopes
En arrière-plan, chaque ServiceDescriptor dans IServiceCollection est compilé dans une méthode
de fabrique Func<ServiceProvider, object> où object est le type de retour et correspond à:
l'instance créée du type Implementation, Singleton ou votre propre méthode de fabrique définie.
https://riptutorial.com/fr/home 76
Résultat
Nous avons maintenant un objet ConcurrentDictionary<Type, Func<ServiceProvider, object>> que
nous pouvons utiliser simultanément pour demander de créer des services pour nous. Pour
montrer un exemple de base de ce à quoi cela aurait pu ressembler.
Ce ConcurrentDictionary est une propriété du ServiceTable qui est une propriété du ServiceProvider
https://riptutorial.com/fr/home 77
Chapitre 13: Injection de services dans des
vues
Syntaxe
• @inject<NameOfService><Identifier>
• @<Identifier>.Foo()
• @inject <type> <nom>
Examples
La directive @inject
ASP.NET Core introduit le concept d'injection de dépendance dans Views via la directive @inject
via la syntaxe suivante:
Exemple d'utilisation
L'ajout de cette directive dans votre View génère essentiellement une propriété du type donné en
utilisant le nom donné dans votre View en utilisant une injection de dépendance appropriée,
comme illustré dans l'exemple ci-dessous:
<!-- This would call the service, which is already populated and output the results -->
There are <b>@WidgetService.GetWidgetCount()</b> Widgets here.
Configuration requise
Les services qui utilisent l'injection de dépendance doivent toujours être enregistrés dans la
méthode ConfigureServices() du fichier Startup.cs et définis en conséquence:
services.AddTransient<IWidgetService, WidgetService>();
}
https://riptutorial.com/fr/home 78
Chapitre 14: La gestion des erreurs
Examples
Rediriger vers une page d'erreur personnalisée
ASP.NET Core fournit le middleware de pages de codes d'état , qui prend en charge plusieurs
méthodes d'extension différentes, mais nous sommes intéressants dans UseStatusCodePages et
UseStatusCodePagesWithRedirects :
});
app.UseStatusCodePagesWithRedirects("~/errors/{0}");
UseExceptionHandler peut être utilisé pour gérer les exceptions globalement. Vous pouvez
obtenir tous les détails de l'objet d'exception, comme Stack Trace, Inner exception et autres. Et
puis vous pouvez les montrer à l'écran. Vous pouvez facilement mettre en œuvre comme ça.
app.UseExceptionHandler(
options => {
options.Run(
async context =>
{
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
context.Response.ContentType = "text/html";
var ex = context.Features.Get<IExceptionHandlerFeature>();
if (ex != null)
{
var err = $"<h1>Error: {ex.Error.Message}</h1>{ex.Error.StackTrace }";
await context.Response.WriteAsync(err).ConfigureAwait(false);
}
https://riptutorial.com/fr/home 79
});
}
);
https://riptutorial.com/fr/home 80
Chapitre 15: Le routage
Examples
Routage de base
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
Contraintes de routage
Il est possible de créer une contrainte de routage personnalisée qui peut être utilisée dans des
routes pour contraindre un paramètre à des valeurs ou à un modèle spécifiques.
Cette contrainte correspondra à un modèle de culture / locale typique, comme en-US, de-DE, zh-
CHT, zh-Hant.
return LocalePattern.IsMatch(locale);
}
}
Par la suite, la contrainte doit être enregistrée avant de pouvoir être utilisée dans les itinéraires.
services.Configure<RouteOptions>(options =>
{
options.ConstraintMap.Add("locale", typeof(LocaleConstraint));
});
https://riptutorial.com/fr/home 81
Utilisation sur les contrôleurs
[Route("api/{culture:locale}/[controller]")]
public class ProductController : Controller { }
https://riptutorial.com/fr/home 82
Chapitre 16: Limitation de débit
Remarques
AspNetCoreRateLimit est une solution de limitation de débit ASP.NET Core open source conçue
pour contrôler le taux de requêtes que les clients peuvent adresser à une API Web ou à une
application MVC en fonction de l'adresse IP ou de l'ID client.
Examples
Limitation de débit basée sur l'adresse IP du client
Avec le middleware IpRateLimit, vous pouvez définir plusieurs limites pour différents scénarios,
comme autoriser une plage IP ou IP à effectuer un nombre maximum d'appels dans un intervalle
de temps de 15 minutes, etc. Vous pouvez définir ces limites pour adresser toutes les requêtes
API ou vous pouvez définir les limites de chaque chemin d'URL ou verbe et chemin HTTP.
Installer
NuGet installer :
Install-Package AspNetCoreRateLimit
Code Startup.cs :
https://riptutorial.com/fr/home 83
loggerFactory.AddDebug();
app.UseIpRateLimiting();
app.UseMvc();
}
Vous devez enregistrer le middleware avant tout autre composant, à l'exception de loggerFactory.
Si vous chargez votre application, vous devez utiliser IDistributedCache avec Redis ou SQLServer
pour que toutes les instances de IDistributedCache aient le même magasin de limites de débit. Au
lieu des magasins en mémoire, vous devez injecter les magasins distribués comme ceci:
"IpRateLimiting": {
"EnableEndpointRateLimiting": false,
"StackBlockedRequests": false,
"RealIpHeader": "X-Real-IP",
"ClientIdHeader": "X-ClientId",
"HttpStatusCode": 429,
"IpWhitelist": [ "127.0.0.1", "::1/10", "192.168.0.0/24" ],
"EndpointWhitelist": [ "get:/api/license", "*:/api/status" ],
"ClientWhitelist": [ "dev-id-1", "dev-id-2" ],
"GeneralRules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 2
},
{
"Endpoint": "*",
"Period": "15m",
"Limit": 100
},
{
"Endpoint": "*",
"Period": "12h",
"Limit": 1000
},
{
"Endpoint": "*",
"Period": "7d",
"Limit": 10000
}
]
}
Si EnableEndpointRateLimiting est défini sur false les limites s'appliquent globalement et seules les
règles ayant pour point de terminaison * seront appliquées. Par exemple, si vous définissez une
limite de 5 appels par seconde, tout appel HTTP à un noeud final sera comptabilisé dans cette
limite.
https://riptutorial.com/fr/home 84
Si EnableEndpointRateLimiting est défini sur true les limites s'appliquent à chaque noeud final,
comme dans {HTTP_Verb}{PATH} . Par exemple, si vous définissez une limite de 5 appels par
seconde pour *:/api/values un client peut appeler GET /api/values 5 fois par seconde mais
également 5 fois PUT /api/values .
Si StackBlockedRequests est défini sur false appels rejetés ne sont pas ajoutés au compteur
d'accélération. Si un client effectue 3 requêtes par seconde et que vous définissez une limite d'un
appel par seconde, les autres limites, telles que les compteurs par minute ou par jour, enregistrent
uniquement le premier appel, celui qui n'a pas été bloqué. Si vous souhaitez que les demandes
rejetées soient comptabilisées dans les autres limites, vous devez définir StackBlockedRequests sur
true .
RealIpHeader est utilisé pour extraire l'adresse IP du client lorsque votre serveur Kestrel se trouve
derrière un proxy inverse. Si votre proxy utilise un en-tête différent, X-Real-IP utilise cette option
pour le configurer.
ClientIdHeader est utilisé pour extraire l'ID client pour la liste blanche, si un identifiant client est
présent dans cet en-tête et correspond à une valeur spécifiée dans ClientWhitelist, aucune limite
de taux n'est appliquée.
"IpRateLimitPolicies": {
"IpRules": [
{
"Ip": "84.247.85.224",
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 10
},
{
"Endpoint": "*",
"Period": "15m",
"Limit": 200
}
]
},
{
"Ip": "192.168.3.22/25",
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 5
},
{
"Endpoint": "*",
"Period": "15m",
"Limit": 150
},
{
"Endpoint": "*",
"Period": "12h",
https://riptutorial.com/fr/home 85
"Limit": 500
}
]
}
]
}
Une règle est composée d'un noeud final, d'une période et d'une limite.
Le format du point de terminaison est {HTTP_Verb}:{PATH} , vous pouvez cibler n'importe quel verbe
HTTP en utilisant le symbole astérisque.
Le format de période est {INT}{PERIOD_TYPE} , vous pouvez utiliser l'un des types de période
suivants: s, m, h, d .
Exemples :
{
"Endpoint": "*",
"Period": "1s",
"Limit": 2
}
Si, à partir de la même adresse IP, dans la même seconde, vous effectuerez 3 appels GET vers
api / valeurs, le dernier appel sera bloqué. Mais si, dans la même seconde, vous appelez PIT api /
values, la requête sera transmise parce que le point de terminaison est différent. Lorsque la
limitation de la fréquence d'extrémité est activée, chaque appel est limité par le taux basé sur
{HTTP_Verb}{PATH} .
Le taux limite les appels avec n'importe quel verbe HTTP à /api/values à 5 appels par 15 minutes:
{
"Endpoint": "*:/api/values",
"Period": "15m",
"Limit": 5
}
{
"Endpoint": "get:/api/values",
"Period": "1h",
"Limit": 5
https://riptutorial.com/fr/home 86
}
Si, à partir de la même adresse IP, vous effectuez 6 appels GET vers api / valeurs, le dernier
appel sera bloqué. Mais si, dans la même heure, vous appelez GET api / values / 1, la requête est
transmise parce que le point de terminaison est différent.
Comportement
• extrait l'adresse IP, l'identifiant du client, le verbe HTTP et l'URL de l'objet de requête, si
vous souhaitez implémenter votre propre logique d'extraction, vous pouvez remplacer l'
IpRateLimitMiddleware.SetIdentity
• recherche l'adresse IP, l'identifiant du client et l'URL dans les listes blanches, s'il y a des
correspondances, aucune action n'est prise
• recherche dans les règles IP pour une correspondance, toutes les règles qui s'appliquent
sont regroupées par période, pour chaque période la règle la plus restrictive est utilisée
• recherche dans les règles générales une correspondance, si une règle générale qui
correspond à une période définie n'est pas présente dans les règles IP, cette règle générale
est également utilisée
• pour chaque règle de correspondance, le compteur de limite de débit est incrémenté, si la
valeur du compteur est supérieure à la limite de la règle, la requête est bloquée
Si la requête est bloquée, le client reçoit une réponse textuelle comme ceci:
Si la demande ne reçoit pas de taux limité, la plus longue période définie dans les règles de
correspondance est utilisée pour composer les en-têtes X-Rate-Limit, ces en-têtes sont injectés
dans la réponse:
https://riptutorial.com/fr/home 87
info: AspNetCoreRateLimit.IpRateLimitMiddleware[0]
Request get:/api/values from IP 84.247.85.224 has been blocked, quota 2/1m exceeded by
3. Blocked by rule *:/api/value, TraceIdentifier 0HKTLISQQVV9D.
Au démarrage de l'application, les règles de limite de débit IP définies dans appsettings.json sont
chargées dans le cache par MemoryCacheClientPolicyStore ou DistributedCacheIpPolicyStore selon
le type de fournisseur de cache utilisé. Vous pouvez accéder au magasin de règles Ip dans un
contrôleur et modifier les règles IP comme suit:
[HttpGet]
public IpRateLimitPolicies Get()
{
return _ipPolicyStore.Get(_options.IpPolicyPrefix);
}
[HttpPost]
public void Post()
{
var pol = _ipPolicyStore.Get(_options.IpPolicyPrefix);
pol.IpRules.Add(new IpRateLimitPolicy
{
Ip = "8.8.4.4",
Rules = new List<RateLimitRule>(new RateLimitRule[] {
new RateLimitRule {
Endpoint = "*:/api/testupdate",
Limit = 100,
Period = "1d" }
})
});
_ipPolicyStore.Set(_options.IpPolicyPrefix, pol);
}
}
De cette façon, vous pouvez stocker les limites de taux IP dans une base de données et les
mettre en cache après le démarrage de chaque application.
Avec le middleware ClientRateLimit, vous pouvez définir plusieurs limites pour différents
scénarios, comme autoriser un client à effectuer un nombre maximal d'appels par intervalle de
https://riptutorial.com/fr/home 88
temps, par seconde, 15 minutes, etc. Vous pouvez définir ces limites pour adresser toutes les
requêtes adressées à une API peut couvrir les limites de chaque chemin d'URL ou de verbe et
chemin HTTP.
Installer
NuGet installer :
Install-Package AspNetCoreRateLimit
Code Startup.cs :
services.Configure<ClientRateLimitOptions>(Configuration.GetSection("ClientRateLimiting"));
services.Configure<ClientRateLimitPolicies>(Configuration.GetSection("ClientRateLimitPolicies"));
app.UseClientRateLimiting();
app.UseMvc();
}
Vous devez enregistrer le middleware avant tout autre composant, à l'exception de loggerFactory.
Si vous chargez votre application, vous devez utiliser IDistributedCache avec Redis ou SQLServer
pour que toutes les instances de IDistributedCache aient le même magasin de limites de débit. Au
lieu des magasins en mémoire, vous devez injecter les magasins distribués comme ceci:
https://riptutorial.com/fr/home 89
services.AddSingleton<IRateLimitCounterStore,DistributedCacheRateLimitCounterStore>();
"ClientRateLimiting": {
"EnableEndpointRateLimiting": false,
"StackBlockedRequests": false,
"ClientIdHeader": "X-ClientId",
"HttpStatusCode": 429,
"EndpointWhitelist": [ "get:/api/license", "*:/api/status" ],
"ClientWhitelist": [ "dev-id-1", "dev-id-2" ],
"GeneralRules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 2
},
{
"Endpoint": "*",
"Period": "15m",
"Limit": 100
},
{
"Endpoint": "*",
"Period": "12h",
"Limit": 1000
},
{
"Endpoint": "*",
"Period": "7d",
"Limit": 10000
}
]
}
Si EnableEndpointRateLimiting est défini sur false les limites s'appliquent globalement et seules les
règles ayant pour point de terminaison * seront appliquées. Par exemple, si vous définissez une
limite de 5 appels par seconde, tout appel HTTP à un noeud final sera comptabilisé dans cette
limite.
Si EnableEndpointRateLimiting est défini sur true les limites s'appliquent à chaque noeud final,
comme dans {HTTP_Verb}{PATH} . Par exemple, si vous définissez une limite de 5 appels par
seconde pour *:/api/values un client peut appeler GET /api/values 5 fois par seconde mais
également 5 fois PUT /api/values .
Si StackBlockedRequests est défini sur false appels rejetés ne sont pas ajoutés au compteur
d'accélération. Si un client effectue 3 requêtes par seconde et que vous définissez une limite d'un
appel par seconde, les autres limites, telles que les compteurs par minute ou par jour, enregistrent
uniquement le premier appel, celui qui n'a pas été bloqué. Si vous souhaitez que les demandes
rejetées soient comptabilisées dans les autres limites, vous devez définir StackBlockedRequests sur
true .
ClientIdHeader est utilisé pour extraire l'ID du client, si un identifiant de client est présent dans cet
en-tête et correspond à une valeur spécifiée dans ClientWhitelist, aucune limite de taux n'est
https://riptutorial.com/fr/home 90
appliquée.
"ClientRateLimitPolicies": {
"ClientRules": [
{
"ClientId": "client-id-1",
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 10
},
{
"Endpoint": "*",
"Period": "15m",
"Limit": 200
}
]
},
{
"Client": "client-id-2",
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 5
},
{
"Endpoint": "*",
"Period": "15m",
"Limit": 150
},
{
"Endpoint": "*",
"Period": "12h",
"Limit": 500
}
]
}
]
}
Une règle est composée d'un noeud final, d'une période et d'une limite.
Le format du point de terminaison est {HTTP_Verb}:{PATH} , vous pouvez cibler n'importe quel verbe
HTTP en utilisant le symbole astérisque.
Le format de période est {INT}{PERIOD_TYPE} , vous pouvez utiliser l'un des types de période
suivants: s, m, h, d .
Exemples :
https://riptutorial.com/fr/home 91
Le taux limite tous les points de terminaison à 2 appels par seconde:
{
"Endpoint": "*",
"Period": "1s",
"Limit": 2
}
Si, dans la même seconde, un client effectue 3 appels GET vers api / valeurs, le dernier appel
sera bloqué. Mais si, dans la même seconde, il appelle PIT api / values, la requête passera par un
point final différent. Lorsque la limitation de la fréquence d'extrémité est activée, chaque appel est
limité par le taux basé sur {HTTP_Verb}{PATH} .
Le taux limite les appels avec n'importe quel verbe HTTP à /api/values à 5 appels par 15 minutes:
{
"Endpoint": "*:/api/values",
"Period": "15m",
"Limit": 5
}
{
"Endpoint": "get:/api/values",
"Period": "1h",
"Limit": 5
}
Si dans une heure, un client effectue 6 appels GET vers api / valeurs, le dernier appel sera
bloqué. Mais si dans la même heure il appelle GET api / values / 1 aussi, la requête passera parce
que c'est un point final différent.
Comportement
• extrait l'ID du client, le verbe HTTP et l'URL de l'objet de requête, si vous souhaitez
implémenter votre propre logique d'extraction, vous pouvez remplacer
ClientRateLimitMiddleware.SetIdentity
• recherche l'identifiant et l'URL du client dans les listes blanches, s'il y a des
correspondances, aucune action n'est prise
• recherche dans le client les règles d'une correspondance, toutes les règles qui s'appliquent
sont regroupées par période, pour chaque période la règle la plus restrictive est utilisée
• recherche dans les règles générales une correspondance, si une règle générale qui
correspond à une période définie est absente des règles du client, cette règle générale est
également utilisée
• pour chaque règle de correspondance, le compteur de limite de débit est incrémenté, si la
valeur du compteur est supérieure à la limite de la règle, la requête est bloquée
https://riptutorial.com/fr/home 92
Si la requête est bloquée, le client reçoit une réponse textuelle comme ceci:
Si la demande ne reçoit pas de taux limité, la plus longue période définie dans les règles de
correspondance est utilisée pour composer les en-têtes X-Rate-Limit, ces en-têtes sont injectés
dans la réponse:
info: AspNetCoreRateLimit.ClientRateLimitMiddleware[0]
Request get:/api/values from ClientId client-id-1 has been blocked, quota 2/1m exceeded
by 3. Blocked by rule *:/api/value, TraceIdentifier 0HKTLISQQVV9D.
Au démarrage de l'application, les règles de limite de débit du client définies dans appsettings.json
sont chargées dans le cache par MemoryCacheClientPolicyStore ou
DistributedCacheClientPolicyStore selon le type de fournisseur de cache utilisé. Vous pouvez
accéder au magasin de règles client dans un contrôleur et modifier les règles comme suit:
[HttpGet]
public ClientRateLimitPolicy Get()
{
return _clientPolicyStore.Get($"{_options.ClientPolicyPrefix}_cl-key-1");
}
https://riptutorial.com/fr/home 93
[HttpPost]
public void Post()
{
var id = $"{_options.ClientPolicyPrefix}_cl-key-1";
var clPolicy = _clientPolicyStore.Get(id);
clPolicy.Rules.Add(new RateLimitRule
{
Endpoint = "*/api/testpolicyupdate",
Period = "1h",
Limit = 100
});
_clientPolicyStore.Set(id, clPolicy);
}
}
De cette façon, vous pouvez stocker les limites de taux client dans une base de données et les
mettre en cache après le démarrage de chaque application.
https://riptutorial.com/fr/home 94
Chapitre 17: Localisation
Examples
Localisation à l'aide de ressources de langage JSON
Dans ASP.NET Core, il existe différentes manières de localiser / globaliser notre application. Il est
important de choisir un moyen adapté à vos besoins. Dans cet exemple, vous verrez comment
créer une application ASP.NET Core multilingue qui lit des chaînes spécifiques à une langue à
partir de fichiers .json et les stocke en mémoire pour assurer la localisation dans toutes les
sections de l’application et maintenir des performances élevées.
Remarques:
1. L’espace de noms de ce projet est DigitalShop que vous pouvez modifier dans votre propre
espace de noms de projets.
2. Envisagez de créer un nouveau projet afin de ne pas rencontrer d'erreurs étranges
3. En aucun cas cet exemple ne montre les meilleures pratiques, donc si vous pensez que cela
peut être amélioré, veuillez le modifier
Pour commencer, ajoutons les packages suivants à la section dependencies existante du fichier
project.json :
"Microsoft.EntityFrameworkCore": "1.0.0",
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.0",
"Microsoft.EntityFrameworkCore.InMemory": "1.0.0"
Maintenant , nous allons remplacer le Startup.cs fichier: ( en using les états sont supprimés car ils
peuvent être facilement ajoutés plus tard)
Startup.cs
namespace DigitalShop
{
public class Startup
{
public static string UiCulture;
public static string CultureDirection;
public static IStringLocalizer _e; // This is how we access language strings
https://riptutorial.com/fr/home 95
this is where we store apps configuration including language
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
LocalConfig = Configuration;
}
// This method gets called by the runtime. Use this method to add services to the
container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddViewLocalization().AddDataAnnotationsLocalization();
// IoC Container
// Add application services.
services.AddTransient<EFStringLocalizerFactory>();
services.AddSingleton<IConfiguration>(Configuration);
}
// This method gets called by the runtime. Use this method to configure the HTTP
request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory
loggerFactory, EFStringLocalizerFactory localizerFactory)
{
_e = localizerFactory.Create(null);
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
https://riptutorial.com/fr/home 96
if (httpContext == null)
{
throw new ArgumentNullException(nameof(httpContext));
}
culture = culture ?? "fa-IR"; // Use the value defined in config files or the
default value
uiCulture = uiCulture ?? culture;
Startup.UiCulture = uiCulture;
Dans le code ci-dessus, nous ajoutons d'abord trois variables de champs public static que nous
initialiserons ultérieurement à l'aide des valeurs lues dans le fichier de paramètres.
appsettings.json
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"AppOptions": {
"Culture": "en-US", // fa-IR for Persian
"UICulture": "en-US", // same as above
"CultureDirection": "ltr" // rtl for Persian/Arabic/Hebrew
}
}
Models , Services et Languages . Dans le dossier Models , créez un autre dossier nommé Localization
https://riptutorial.com/fr/home 97
.
Dans le dossier Services , nous créons un nouveau fichier .cs nommé EFLocalization . Le contenu
serait: (Encore une fois à l' using ne sont pas inclus déclarations)
EFLocalization.cs
namespace DigitalShop.Services
{
public class EFStringLocalizerFactory : IStringLocalizerFactory
{
private readonly LocalizationDbContext _db;
public EFStringLocalizerFactory()
{
_db = new LocalizationDbContext();
// Here we define all available languages to the app
// available languages are those that have a json and cs file in
// the Languages folder
_db.AddRange(
new Culture
{
Name = "en-US",
Resources = en_US.GetList()
},
new Culture
{
Name = "fa-IR",
Resources = fa_IR.GetList()
}
);
_db.SaveChanges();
}
https://riptutorial.com/fr/home 98
null);
}
}
https://riptutorial.com/fr/home 99
var value = string.Format(format ?? name, arguments);
return new LocalizedString(name, value, resourceNotFound: format == null);
}
}
Culture.cs
namespace DigitalShop.Models.Localization
{
public class Culture
{
public int Id { get; set; }
public string Name { get; set; }
public virtual List<Resource> Resources { get; set; }
}
}
Resource.cs
namespace DigitalShop.Models.Localization
{
public class Resource
{
public int Id { get; set; }
public string Key { get; set; }
https://riptutorial.com/fr/home 100
public string Value { get; set; }
public virtual Culture Culture { get; set; }
}
}
LocalizationDbContext.cs
namespace DigitalShop.Models.Localization
{
public class LocalizationDbContext : DbContext
{
public DbSet<Culture> Cultures { get; set; }
public DbSet<Resource> Resources { get; set; }
Les fichiers ci-dessus ne sont que des modèles qui seront remplis avec des ressources
linguistiques, des cultures et un DBContext typique utilisé par EF Core.
La dernière chose dont nous avons besoin pour faire tout ce travail est de créer les fichiers de
ressources linguistiques. Les fichiers JSON utilisés pour stocker une paire clé-valeur pour
différentes langues disponibles dans votre application.
Dans cet exemple, notre application ne dispose que de deux langues. Anglais et persan. Pour
chacune des langues, nous avons besoin de deux fichiers. Un fichier JSON contenant des paires
clé-valeur et un fichier .cs contenant une classe portant le même nom que le fichier JSON. Cette
classe a une méthode, GetList qui désérialise le fichier JSON et le renvoie. Cette méthode est
appelée dans le constructeur de EFStringLocalizerFactory que nous avons créé précédemment.
en-US.cs
namespace DigitalShop.Languages
{
public static class en_US
{
public static List<Resource> GetList()
{
var jsonSerializerSettings = new JsonSerializerSettings();
jsonSerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore;
return
JsonConvert.DeserializeObject<List<Resource>>(File.ReadAllText("Languages/en-US.json"),
jsonSerializerSettings);
}
}
}
en-US.json
https://riptutorial.com/fr/home 101
[
{
"Key": "Welcome",
"Value": "Welcome"
},
{
"Key": "Hello",
"Value": "Hello"
},
]
fa-IR.cs
fa-IR.json
[
{
"Key": "Welcome",
"Value": ""دیدمآ شوخ
},
{
"Key": "Hello",
"Value": ""مالس
},
]
Nous avons tous fini. Maintenant, pour accéder aux chaînes de langue (paires clé-valeur)
n'importe où dans votre code ( .cs ou .cshtml ), vous pouvez effectuer les opérations suivantes:
<h1>@Startup._e["Welcome"]</h1>
• Si vous essayez d'accéder à une Key qui n'existe pas dans le fichier JSON ou chargé, vous
obtiendrez juste le littéral clé (dans l'exemple ci - dessus, en essayant d'accéder
Startup._e["How are you"] - How are you Startup._e["How are you"] retournerez How are you -
https://riptutorial.com/fr/home 102
How are youpeu importe les paramètres linguistiques, car il n'existe pas
• Si vous modifiez une valeur de chaîne dans un fichier de langue .json , vous devrez
redémarrer l'application. Sinon, il affichera simplement la valeur par défaut (nom de la clé).
Ceci est particulièrement important lorsque vous exécutez votre application sans
déboguer.
• Le appsettings.json peut être utilisé pour stocker toutes sortes de paramètres dont votre
application peut avoir besoin
• Le redémarrage de l'application n'est pas nécessaire si vous souhaitez simplement modifier
les paramètres de langue / culture du fichier appsettings.json . Cela signifie que vous
pouvez avoir une option dans l'interface de vos applications pour permettre aux utilisateurs
de modifier la langue / culture au moment de l'exécution.
Par défaut, le middleware Request Localization intégré prend uniquement en charge la définition
de la culture via une requête, un cookie ou un en Accept-Language tête Accept-Language . Cet
exemple montre comment créer un middleware qui permet de définir la culture comme faisant
partie du chemin comme dans /api/en-US/products .
Cet exemple de middleware suppose que les paramètres régionaux se trouvent dans le deuxième
segment du chemin.
https://riptutorial.com/fr/home 103
public class UrlRequestCultureProvider : RequestCultureProvider
{
private static readonly Regex LocalePattern = new Regex(@"^[a-z]{2}(-[a-z]{2,4})?$",
RegexOptions.IgnoreCase);
if (!LocalePattern.IsMatch(parts[2]))
{
return Task.FromResult<ProviderCultureResult>(null);
}
Enregistrement du middleware
var localizationOptions = new RequestLocalizationOptions
{
SupportedCultures = new List<CultureInfo>
{
new CultureInfo("de-DE"),
new CultureInfo("en-US"),
new CultureInfo("en-GB")
},
SupportedUICultures = new List<CultureInfo>
{
new CultureInfo("de-DE"),
new CultureInfo("en-US"),
new CultureInfo("en-GB")
},
DefaultRequestCulture = new RequestCulture("en-US")
};
https://riptutorial.com/fr/home 104
Options = localizationOptions
});
app.UseRequestLocalization(localizationOptions);
Enregistrer l'itinéraire
Exemple d'enregistrement des routes sans utiliser de contraintes personnalisées
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "api/{culture::regex(^[a-z]{{2}}-[A-Za-z]{{4}}$)}}/{controller}/{id?}");
routes.MapRoute(
name: "default",
template: "api/{controller}/{id?}");
});
https://riptutorial.com/fr/home 105
Chapitre 18: Middleware
Remarques
Le middleware est un composant logiciel qui détermine comment traiter la demande et décide de
la transmettre au composant suivant du pipeline d'applications. Chaque middleware a un rôle et
des actions spécifiques à exécuter sur la demande.
Examples
Utilisation du middleware ExceptionHandler pour envoyer une erreur JSON
personnalisée au client
// other fields
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
context.Response.StatusCode = 500; // or another Status
context.Response.ContentType = "application/json";
https://riptutorial.com/fr/home 106
});
await nextMiddleware.Invoke(context);
}
De la documentation :
Vous pouvez y accéder simplement en attribuant une valeur à une entrée à clé ou en demandant
la valeur d'une clé donnée.
Par exemple, certains Middleware simples pourraient ajouter quelque chose à la collection Items:
https://riptutorial.com/fr/home 107
et plus tard, un autre middleware pourrait y accéder:
Courir
Termine la chaîne. Aucune autre méthode de middleware ne fonctionnera après cela. Devrait être
placé à la fin de tout pipeline.
Utilisation
https://riptutorial.com/fr/home 108
MapWhen
Carte
Similaire à MapWhen. Exécute le middleware si le chemin demandé par l'utilisateur est égal au
chemin fourni en paramètre.
https://riptutorial.com/fr/home 109
Chapitre 19: Mise en cache
Introduction
La mise en cache permet d'améliorer les performances d'une application en conservant une copie
facilement accessible des données. Aspnet Core est livré avec deux abstractions de mise en
cache faciles à utiliser et à tester.
La mémoire cache stockera les données dans la mémoire cache du serveur local.
Examples
Utilisation du cache InMemory dans l'application ASP.NET Core
Pour utiliser un cache en mémoire dans votre application ASP.NET, ajoutez les dépendances
suivantes à votre fichier project.json :
"Microsoft.Extensions.Caching.Memory": "1.0.0-rc2-final",
services.AddMemoryCache();
Pour ajouter des éléments au cache dans notre application, nous utiliserons IMemoryCache qui peut
être injecté dans n'importe quelle classe (par exemple Controller), comme indiqué ci-dessous.
Utilisez la méthode Set pour écrire dans le cache. Set accepte la clé à utiliser pour rechercher la
valeur, la valeur à mettre en cache et un ensemble de MemoryCacheEntryOptions .
https://riptutorial.com/fr/home 110
MemoryCacheEntryOptions vous permet de spécifier une expiration absolue ou en temps réel du
cache, une priorité de mise en cache, des rappels et des dépendances. Un des échantillons ci-
dessous-
_memoryCache.Set(cacheKey, greeting,
new MemoryCacheEntryOptions()
.SetAbsoluteExpiration(TimeSpan.FromMinutes(1)));
Pour exploiter le cache distribué, vous devez référencer l'une des implémentations disponibles:
• Redis
• Serveur SQL
[HttpGet]
public async Task<Books[]> GetAllBooks() {
var serialized = this.distributedCache.GetStringAsync($"allbooks");
Books[] books = null;
if (string.IsNullOrEmpty(serialized)) {
books = await Books.FetchAllAsync();
this.distributedCache.SetStringAsync($"allbooks",
JsonConvert.SerializeObject(books));
} else {
books = JsonConvert.DeserializeObject<Books[]>(serialized);
}
return books;
}
}
https://riptutorial.com/fr/home 111
Chapitre 20: project.json
Introduction
Project json est une structure de fichier de configuration de projet, utilisée temporairement par les
projets asp.net-core, avant que Microsoft ne retourne dans les fichiers csproj en faveur de
msbuild.
Examples
Exemple de projet de bibliothèque simple
{
"version": "1.0.0",
"dependencies": {
"NETStandard.Library": "1.6.1", //nuget dependency
},
"frameworks": { //frameworks the library is build for
"netstandard1.6": {}
},
"buildOptions": {
"debugType": "portable"
}
}
{
"name": String, //The name of the project, used for the assembly name as well as the name of
the package. The top level folder name is used if this property is not specified.
"version": String, //The Semver version of the project, also used for the NuGet package.
"description": String, //A longer description of the project. Used in the assembly properties.
"copyright": String, //The copyright information for the project. Used in the assembly
properties.
"title": String, //The friendly name of the project, can contain spaces and special characters
not allowed when using the `name` property. Used in the assembly properties.
"entryPoint": String, //The entrypoint method for the project. `Main` by default.
"testRunner": String, //The name of the test runner, such as NUnit or xUnit, to use with this
project. Setting this also marks the project as a test project.
"authors": String[], // An array of strings with the names of the authors of the project.
"language": String, //The (human) language of the project. Corresponds to the "neutral-
language" compiler argument.
"embedInteropTypes": Boolean, //`true` to embed COM interop types in the assembly; otherwise,
`false`.
"preprocess": String or String[], //Specifies which files are included in preprocessing.
"shared": String or String[], //Specifies which files are shared, this is used for library
export.
"dependencies": Object { //project and nuget dependencies
https://riptutorial.com/fr/home 112
version: String, //Specifies the version or version range of the dependency. Use the \*
wildcard to specify a floating dependency version.
type: String, //type of dependency: build
target: String, //Restricts the dependency to match only a `project` or a `package`.
include: String,
exclude: String,
suppressParent: String
},
"tools": Object, //An object that defines package dependencies that are used as tools for the
current project, not as references. Packages defined here are available in scripts that run
during the build process, but they are not accessible to the code in the project itself. Tools
can for example include code generators or post-build tools that perform tasks related to
packing.
"scripts": Object, // commandline scripts: precompile, postcompile, prepublish & postpublish
"buildOptions": Object {
"define": String[], //A list of defines such as "DEBUG" or "TRACE" that can be used in
conditional compilation in the code.
"nowarn": String[], //A list of warnings to ignore.
"additionalArguments": String[], //A list of extra arguments that will be passed to the
compiler.
"warningsAsErrors": Boolean,
"allowUnsafe": Boolean,
"emitEntryPoint": Boolean,
"optimize": Boolean,
"platform": String,
"languageVersion": String,
"keyFile": String,
"delaySign": Boolean,
"publicSign": Boolean,
"debugType": String,
"xmlDoc": Boolean,
"preserveCompilationContext": Boolean,
"outputName": String,
"compilerName": String,
"compile": Object {
"include": String or String[],
"exclude": String or String[],
"includeFiles": String or String[],
"excludeFiles": String or String[],
"builtIns": Object,
"mappings": Object
},
"embed": Object {
"include": String or String[],
"exclude": String or String[],
"includeFiles": String or String[],
"excludeFiles": String or String[],
"builtIns": Object,
"mappings": Object
},
"copyToOutput": Object {
"include": String or String[],
"exclude": String or String[],
"includeFiles": String or String[],
"excludeFiles": String or String[],
"builtIns": Object,
"mappings": Object
}
},
"publishOptions": Object {
"include": String or String[],
https://riptutorial.com/fr/home 113
"exclude": String or String[],
"includeFiles": String or String[],
"excludeFiles": String or String[],
"builtIns": Object,
"mappings": Object
},
"runtimeOptions": Object {
"configProperties": Object {
"System.GC.Server": Boolean,
"System.GC.Concurrent": Boolean,
"System.GC.RetainVM": Boolean,
"System.Threading.ThreadPool.MinThreads": Integer,
"System.Threading.ThreadPool.MaxThreads": Integer
},
"framework": Object {
"name": String,
"version": String,
},
"applyPatches": Boolean
},
"packOptions": Object {
"summary": String,
"tags": String[],
"owners": String[],
"releaseNotes": String,
"iconUrl": String,
"projectUrl": String,
"licenseUrl": String,
"requireLicenseAcceptance": Boolean,
"repository": Object {
"type": String,
"url": String
},
"files": Object {
"include": String or String[],
"exclude": String or String[],
"includeFiles": String or String[],
"excludeFiles": String or String[],
"builtIns": Object,
"mappings": Object
}
},
"analyzerOptions": Object {
"languageId": String
},
"configurations": Object,
"frameworks": Object {
"dependencies": Object {
version: String,
type: String,
target: String,
include: String,
exclude: String,
suppressParent: String
},
"frameworkAssemblies": Object,
"wrappedProject": String,
"bin": Object {
assembly: String
}
},
https://riptutorial.com/fr/home 114
"runtimes": Object,
"userSecretsId": String
}
Un exemple simple de configuration de projet pour une application console .NetCore 1.1
{
"version": "1.0.0",
"buildOptions": {
"emitEntryPoint": true // make sure entry point is emitted.
},
"dependencies": {
},
"tools": {
},
"frameworks": {
"netcoreapp1.1": { // run as console app
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.1.0"
}
},
"imports": "dnxcore50"
}
},
}
https://riptutorial.com/fr/home 115
Chapitre 21: Publication et déploiement
Examples
Crécerelle. Configuration de l'adresse d'écoute
En utilisant Kestrel, vous pouvez spécifier le port en utilisant les approches suivantes:
les fenêtres
SET ASPNETCORE_URLS=https://0.0.0.0:5001
OS X
export ASPNETCORE_URLS=https://0.0.0.0:5001
{
"server.urls": "http://<ip address>:<port>"
}
• écoutez 5000 sur toutes les adresses IP4 et IP6 depuis n'importe quelle interface:
"server.urls": "http://*:5000"
ou
"server.urls": "http://::5000;http://0.0.0.0:5000"
https://riptutorial.com/fr/home 116
• écoutez 5000 sur chaque adresse IP4:
"server.urls": "http://0.0.0.0:5000"
"publishOptions": {
"include": [
"hosting.json",
...
]
}
host.Run();
}
https://riptutorial.com/fr/home 117
Chapitre 22: Regroupement et Minification
Examples
Grunt et Gulp
Dans les applications ASP.NET Core, vous regroupez et gérez les ressources côté client pendant
la conception à l'aide d'outils tiers, tels que Gulp et Grunt . En utilisant le regroupement et la
minification au moment du design, les fichiers minifiés sont créés avant le déploiement de
l'application. Le regroupement et la minimisation avant le déploiement offrent l'avantage de réduire
la charge du serveur. Cependant, il est important de reconnaître que le regroupement et la
minification au moment du design augmentent la complexité de la construction et ne fonctionnent
qu'avec des fichiers statiques.
Cela se fait dans ASP.NET Core en configurant Gulp via un fichier gulpfile.js dans votre projet:
// Defining dependencies
var gulp = require("gulp"),
rimraf = require("rimraf"),
concat = require("gulp-concat"),
cssmin = require("gulp-cssmin"),
uglify = require("gulp-uglify");
// Defining paths
var paths = {
js: webroot + "js/**/*.js",
minJs: webroot + "js/**/*.min.js",
css: webroot + "css/**/*.css",
minCss: webroot + "css/**/*.min.css",
concatJsDest: webroot + "js/site.min.js",
concatCssDest: webroot + "css/site.min.css"
};
Cette approche va regrouper et minimiser correctement vos fichiers Javascript et CSS existants
https://riptutorial.com/fr/home 118
en fonction des répertoires et des modèles de globalisation utilisés.
Visual Studio propose également une extension Bundler and Minifier disponible capable de gérer
ce processus pour vous. L'extension vous permet de sélectionner et de regrouper facilement les
fichiers dont vous avez besoin sans écrire de ligne de code.
Cela vous invitera à nommer votre paquet et à choisir un emplacement pour le sauvegarder. Vous
remarquerez alors un nouveau fichier dans votre projet appelé bundleconfig.json qui ressemble à
ceci:
https://riptutorial.com/fr/home 119
[
{
"outputFileName": "wwwroot/app/bundle.js",
"inputFiles": [
"wwwroot/lib/jquery/dist/jquery.js",
"wwwroot/lib/bootstrap/dist/js/bootstrap.js",
"wwwroot/lib/jquery-validation/dist/jquery.validate.js",
"wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"
]
}
]
REMARQUE: L'ordre dans lequel les fichiers sont sélectionnés déterminera l'ordre
dans lequel ils apparaissent dans l'ensemble, donc si vous avez des dépendances,
assurez-vous d'en tenir compte.
[
{
"outputFileName": "wwwroot/app/bundle.js",
"inputFiles": [
"wwwroot/lib/jquery/dist/jquery.js",
"wwwroot/lib/bootstrap/dist/js/bootstrap.js",
"wwwroot/lib/jquery-validation/dist/jquery.validate.js",
"wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"
],
"minify": {
"enabled": true
}
}
]
https://riptutorial.com/fr/home 120
Après cela, vos ensembles doivent être automatiquement mis à jour à l’étape que vous avez
sélectionnée.
Utiliser BundlerMinifier.Core
Pour utiliser cet outil, ajoutez simplement une référence à BundlerMinifier.Core dans la section
des tools de votre fichier project.json existant, comme indiqué ci-dessous:
"tools": {
"BundlerMinifier.Core": "2.0.238",
"Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final",
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
}
[
{
"outputFileName": "wwwroot/css/site.min.css",
"inputFiles": [
"wwwroot/css/site.css"
]
},
{
"outputFileName": "wwwroot/js/site.min.js",
"inputFiles": [
"wwwroot/js/site.js"
],
"minify": {
https://riptutorial.com/fr/home 121
"enabled": true,
"renameLocals": true
},
"sourceMap": false
},
{
"outputFileName": "wwwroot/js/semantic.validation.min.js",
"inputFiles": [
"wwwroot/js/semantic.validation.js"
],
"minify": {
"enabled": true,
"renameLocals": true
}
}
]
dotnet bundle
Groupage automatisé
Le processus de regroupement et de réduction peut être automatisé dans le cadre du processus
de génération en ajoutant la commande dotnet bundle dans la section dotnet bundle de votre
fichier project.json existant:
"scripts": {
"precompile": [
"dotnet bundle"
]
}
Commandes disponibles
Vous pouvez voir une liste de toutes les commandes disponibles et leurs descriptions ci-dessous:
https://riptutorial.com/fr/home 122
core/topic/4051/regroupement-et-minification
https://riptutorial.com/fr/home 123
Chapitre 23: Sessions dans ASP.NET Core
1.0
Introduction
Utilisation de sessions dans ASP.NET Core 1.0
Examples
Exemple de base de manipulation de session
services.AddDistributedMemoryCache(); //This way ASP.NET Core will use a Memory Cache to store
session variables
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromDays(1); // It depends on user requirements.
options.CookieName = ".My.Session"; // Give a cookie name for session which will
be visible in request payloads.
});
using Microsoft.AspNetCore.Http;
return View();
}
}
https://riptutorial.com/fr/home 124
5. Si vous utilisez la stratégie cors, il peut parfois y avoir des erreurs, après avoir activé
session concernant les en-têtes sur l'activation de l'en - tête AllowCredentials et l'utilisation
de
En- tête WithOrigins au lieu de AllowAllOrigins .
https://riptutorial.com/fr/home 125
Chapitre 24: Tag Helpers
Paramètres
prénom Info
asp-
Le nom du contrôleur où la méthode d'action spécifiée dans asp-action existe
controller
Examples
Form Tag Helper - Exemple de base
<form asp-action="create"
asp-controller="Home"
asp-route-returnurl="dashboard"
asp-route-from="google">
<!--Your form elements goes here-->
</form>
Assistant de saisie
En supposant que votre vue est fortement saisie dans un modèle de vue tel que
https://riptutorial.com/fr/home 126
Et vous transmettez un objet de ceci à la vue de votre méthode d'action.
@model CreateProduct
<form asp-action="create" asp-controller="Home" >
</form>
</form>
Si vous souhaitez que le champ de saisie soit rendu avec une valeur par défaut, vous pouvez
définir la valeur de la propriété Name de votre modèle de vue dans la méthode d'action.
En supposant que votre vue est fortement typée dans un modèle de vue comme celui-ci
Et dans votre méthode d'action GET, vous créez un objet de ce modèle de vue, en définissant la
propriété Catégories et en l'envoyant à la vue.
https://riptutorial.com/fr/home 127
new SelectListItem {Text = "Furniture", Value = "2"}
};
return View(vm);
}
et à votre avis
@model CreateProduct
Cela rendra le balisage ci-dessous ( inclus uniquement les parties pertinentes du formulaire /
champs )
Vous pouvez utiliser le même modèle de vue que votre paramètre de méthode d'action HttpPost
[HttpPost]
public ActionResult Create(CreateProduct model)
{
//check model.SelectedCategory value
/ /to do : return something
}
Si vous souhaitez définir une option en tant qu'option sélectionnée, vous pouvez simplement
définir la valeur de la propriété SelectedCategory .
https://riptutorial.com/fr/home 128
return View(vm);
}
Si vous voulez rendre une liste déroulante à sélection multiple, vous pouvez simplement modifier
votre propriété de modèle de vue que vous utilisez asp-for attribut asp-for dans votre vue en un
type de tableau.
Dans la vue
@model CreateProduct
Vous pouvez créer vos propres aides au tag en implémentant ITagHelper ou en dérivant de la
classe de commodité TagHelper .
• La convention par défaut consiste à cibler une balise html correspondant au nom de
l'assistant sans le suffixe facultatif TagHelper. Par exemple, WidgetTagHelper ciblera une
<widget> .
• L'attribut [HtmlTargetElement] peut être utilisé pour contrôler davantage la balise ciblée
• Toute propriété publique de la classe peut recevoir une valeur en tant qu'attribut dans le
balisage de rasoir. Par exemple une propriété public string Title {get; set;} peut recevoir
une valeur comme <widget title="my title">
• Par défaut, tag helpers convertit les noms et les propriétés de la classe C # en cascade pour
les helpers de tag en cas de kebab inférieur. Par exemple, si vous omettez d'utiliser
https://riptutorial.com/fr/home 129
[HtmlTargetElement] et que le nom de la classe est WidgetBoxTagHelper , alors dans Razor,
vous écrirez <widget-box></widget-box> .
• Process et ProcessAsync contiennent la logique de rendu. Les deux reçoivent un paramètre de
contexte avec des informations sur la balise en cours de rendu et un paramètre de sortie
utilisé pour personnaliser le résultat rendu.
Tout assembly contenant des aides de balises personnalisées doit être ajouté au fichier
_ViewImports.cshtml (notez que c'est l'assembly en cours d'enregistrement, pas l'espace de
noms):
@addTagHelper *, MyAssembly
<div class="widget-box">
<div class="widget-header">My Title</div>
<div class="widget-body">This is my content: some message</div>
</div>
[HtmlTargetElement("widget-box")]
public class WidgetTagHelper : TagHelper
{
public string Title { get; set; }
https://riptutorial.com/fr/home 130
}
}
Assistant d'étiquette
Label Tag Helper peut être utilisé pour rendre une label pour une propriété de modèle. Il remplace
la méthode Html.LabelFor dans les versions précédentes de MVC.
Dans la vue, vous pouvez utiliser l’élément HTML label et l’assistant de tag asp-for :
<form>
<label asp-for="Name"></label>
<input asp-for="Name" type="text" />
</form>
Ceci est équivalent au code suivant dans les versions antérieures de MVC:
<form>
@Html.LabelFor(x => x.Name)
@Html.TextBoxFor(x => x.Name)
</form>
<form>
<label for="Name">Name</label>
<input name="Name" id="Name" type="text" value="">
</form>
L'assistant de balise d'ancrage est utilisé pour générer des attributs href afin d'établir un lien avec
une action de contrôleur ou un itinéraire MVC particulier. Exemple de base
Parfois, vous devez spécifier des paramètres supplémentaires pour l'action du contrôleur à
laquelle vous êtes lié. Nous pouvons spécifier des valeurs pour ces paramètres en ajoutant des
attributs avec le préfixe asp-route.
https://riptutorial.com/fr/home 131
Lire Tag Helpers en ligne: https://riptutorial.com/fr/asp-net-core/topic/2665/tag-helpers
https://riptutorial.com/fr/home 132
Chapitre 25: Travailler avec
JavascriptServices
Introduction
Selon la documentation officielle:
Examples
Activation de webpack-dev-middleware pour le projet asp.net-core
Disons que vous utilisez Webpack pour le regroupement frontal. Vous pouvez ajouter webpack-dev-
middleware pour servir vos statistiques via un serveur minuscule et rapide. Il vous permet de
recharger automatiquement vos actifs lorsque le contenu a changé, de servir des statiques en
mémoire sans écrire en continu des versions intermédiaires sur le disque.
Conditions préalables
NuGet
Package d'installation Microsoft.AspNetCore.SpaServices
npm
npm install --save-dev aspnet-webpack, webpack-dev-middleware, webpack-dev-server
Configuration
Étendre la méthode Configure dans votre classe de Startup
if (env.IsDevelopment())
{
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions()
{
ConfigFile = "webpack.config.js" //this is defualt value
});
}
https://riptutorial.com/fr/home 133
Ajouter le remplacement du module chaud (HMR)
Conditions préalables
En plus des webpack-dev-middleware :
Configuration
UseWebpackDevMiddleware simplement à jour la configuration de UseWebpackDevMiddleware avec de
nouvelles options:
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions()
{
ConfigFile = "webpack.config.js", //this is defualt value
HotModuleReplacement = true,
ReactHotModuleReplacement = true, //for React only
});
Vous devez également accepter les modules chauds dans votre code d'application.
Vous pouvez utiliser le générateur aspnetcore-spa pour Yeoman pour créer une toute nouvelle
application à une page avec asp.net core.
Cela vous permet de choisir l'un des frameworks frontaux les plus populaires et génère des
projets avec webpack, dev server, remplacement de module à chaud et fonctionnalités de rendu
côté serveur.
Juste courir
https://riptutorial.com/fr/home 134
Lire Travailler avec JavascriptServices en ligne: https://riptutorial.com/fr/asp-net-
core/topic/9621/travailler-avec-javascriptservices
https://riptutorial.com/fr/home 135
Crédits
S.
Chapitres Contributeurs
No
Afficher les
2 Daniel J.G.
composants
Angular2 et .Net
3 Alejandro Tobón, Sentient Entities
Core
ASP.NET Core -
Journal à la fois de la
4 demande et de la Gubr
réponse à l'aide de
middleware
Configuration de
7 plusieurs dotnetom, Johnny, Robert Paulsen, Sanket, Set, Tseng
environnements
Demandes d'origine
8 Henk Mollema, Sanket, Saqib Rokadia, Tseng
croisée (CORS)
https://riptutorial.com/fr/home 136
dans des vues
La gestion des
14 Sanket, Set
erreurs
Publication et
21 Set
déploiement
Regroupement et
22 Rion Williams, Zach Becknell
Minification
Sessions dans
23 ravindra, Sanket
ASP.NET Core 1.0
24 Tag Helpers Ali, Daniel J.G., dotnetom, Shyju, tmg, Zach Becknell
Travailler avec
25 hmnzr
JavascriptServices
https://riptutorial.com/fr/home 137