Comment définir « l’extérieur » ?
Vous aurez à écrire différents types de logiciels, allant du petit utilitaire aux grands logiciels métier. Quelle que soit leur taille, il s'agira rarement d'applications autonomes tournant dans leur propre environnement. Au contraire, elles auront à interagir avec le stockage local (un disque dur local), communiquer avec d’autres applications locales et utiliser des services à distance via le réseau.
Dans ce chapitre, nous allons aborder trois types d’interactions :
La récupération des données saisies par un utilisateur.
La récupération de données sur Internet.
L'écriture dans un fichier.
Pour cela, nous allons demander à l'utilisateur de saisir une URL (l'adresse d'une page Web). Nous allons ensuite vérifier qu’elle correspond au format d'une URL, puis récupérer le contenu de la page en question et écrire ce contenu dans un fichier.
Récupérez et validez les données saisies par un utilisateur
On peut collecter les données saisies par un utilisateur soit au démarrage de l'application à l’aide d’arguments de ligne de commande, soit en les demandant à l’utilisateur à n'importe quel moment de l’exécution du programme.
Vérifiez les données saisies en ligne de commande
Le code suivant présente une classe DonneeUtilisateur
qui fait partie de l'espace de noms Communication
.
Lorsque les données de l’utilisateur sont fournies au démarrage du programme, elles sont stockées dans l'array args
de la fonction Main
. Dans cet exemple, la fonction Main permet d'effectuer les opérations suivantes :
Vérifier si un argument a été fourni.
Sinon, inviter l’utilisateur à saisir une URL.
Indiquer si l’URL dispose du bon format.
using System;
namespace Communication
{
/// <summary>
/// Démonstration de la récupération et du contrôle des données saisies par un utilisateur
/// </summary>
/// <remarks>L'équipe éducative d'OpenClassrooms</remarks>
public class DonneeUtilisateur
{
/// <summary>
/// Vérifier si l'utilisateur a fourni une URL à partir de la ligne de commande
/// Si ce n'est pas le cas, en demander une
/// Dans tous les cas, vérifier que l’URL est valide !
/// </summary>
/// <param name="args">Soit la variable ne contient rien, soit elle contient une chaîne qui est l'URL</param>
public static void Main(string[] args)
{
string chaineUrl = "";
int nombreArguments;
if (args == null)
{
nombreArguments = 0;
}
else
{
nombreArguments = args.Length;
}
/// Affecter une valeur à chaineUrl ou quitter
switch (nombreArguments)
{
case 0:
chaineUrl = DemanderUneUrl();
break;
case 1:
chaineUrl = args[0];
break;
default:
Console.WriteLine("Veuillez exécuter le programme en spécifiant une URL ou aucun argument");
Environment.Exit(-1);
break;
}
Console.WriteLine("Vérification de l'URL " + chaineUrl);
if (URLValide(chaineUrl))
{
Console.WriteLine(chaineUrl + " est une URL valide");
}
else
{
Console.WriteLine(chaineUrl + " n'est pas une URL valide");
}
}
}
}
Le choix devant se faire en fonction des différentes valeurs possibles d'une expression (la propriété args.Length
), nous allons utiliser une instruction switch
:
Si l'utilisateur n'a fourni aucun argument dans la ligne de commande, args.Length vaut 0. Par conséquent, on appelle la fonction
DemanderUneUrl()
et on affecte son résultat à la variable chaineUrl.Si l'utilisateur a fourni un argument, on suppose qu'il s'agit de l'URL qu'il souhaite fournir. Par conséquent, on affecte directement cette valeur à la variable
chaineUrl
.Si l'utilisateur a fourni plus d'un argument, on ne sait pas quoi faire ! Par conséquent, on quitte avec l'instruction
Environment.Exit(-1)
.
Ça fonctionne ! Implémentons la fonction DemanderUneUrl
.
Demandez des données à l'utilisateur
/// <summary>
/// Demander à l'utilisateur de saisir une URL
/// </summary>
/// <returns>Une représentation sous forme de chaîne de caractères de l'URL saisie par l'utilisateur</returns>.
public static string DemanderUneUrl()
{
Console.WriteLine("Veuillez saisir une URL valide");
string url = Console.ReadLine();
return url;
}
Terminons cette section en vérifiant le format de l'URL saisie.
Contrôlez le format de l'URL saisie
Récupérer les données des utilisateurs est une excellente première étape. Il existe une règle essentielle, tant pour des raisons pratiques que pour des raisons de sécurité : toujours valider les données saisies par l'utilisateur.
Certains utilisateurs feront des erreurs. D'autres essaieront de trouver des moyens de contourner la sécurité de votre application. Pour vérifier que la chaîne fournie par l'utilisateur représente effectivement une URL, C# propose la classe URI, dont la méthode lève une exception si la représentation de la chaîne fournie n'est pas une URL correctement mise en forme.
Voici le code de la fonction URLValide
qui utilise la classe URI.
/// <summary>
/// Vérifier la mise en forme d'une URL
/// </summary>
/// <param name="urlString"></param>
/// <returns>Vrai si le format correspond a une URL, sinon faux<returns>
private static bool URLValide(string chaineUrl)
{
if (Uri.IsWellFormedUriString(chaineUrl, UriKind.Absolute))
{
return true;
}
else
{
return false;
}
}
L'instruction Uri.IsWellFormedUriString(chaineUrl, UriKind.Absolute)
constitue le noyau de ce code.
Si l'URL est correctement mise en forme, l'instanciation fonctionne et renvoie
true
.Si l'URL est un chemin absolu et non un chemin relatif, elle renvoie
true
.Si l'URL n'est pas mise en forme correctement, elle renvoie
false
.
Maintenant que vous avez tous les éléments, exécutons le code.
Testez par vous-même !
Prêt à coder ? Pour accéder à l’exercice, suivez ce lien.
Super ! Maintenant que nous sommes en mesure d'obtenir des données d'entrée et de vérifier qu'il s'agit d'une URL bien formée, nous allons récupérer le contenu de la page à laquelle l'URL fait référence !
Récupérez le contenu d'une URL avec la communication réseau
La communication réseau consiste à gérer un enchaînement de requêtes et de réponses sur un réseau, généralement Internet.
Voici ce que doit accomplir votre code :
Envoyer une requête au serveur et attendre une réponse, ou gérer une absence de connexion au réseau.
Attendre la réponse et traiter la réponse ou l'absence de réponse.
Quelles raisons pourraient expliquer l'absence de réponse ?
Une absence de réponse peut avoir plusieurs explications :
Vous avez envoyé une requête à une mauvaise URL.
Le serveur est indisponible (temporairement ou définitivement).
Le traitement de la requête a pris trop de temps.
Et bien d'autres encore.
Pour le code de requête-réponse, vous devrez :
Vous connecter à la ressource identifiée par l'URL.
Récupérer le contenu et le placer dans une liste.
Connectez-vous à une ressource
Créons une classe PageDistante
dans le même espace de noms Communication
que la classe DonneeUtilisateur
. Cela nous permettra de réutiliser les fonctions créées dans la classe DonneeUtilisateur
.
Dans la fonction Main
de la classe PageDistante
, nous allons demander à l'utilisateur de saisir une URL. Ensuite, nous allons établir une connexion avec la ressource (page) concernée. Enfin, nous allons récupérer le contenu de la ressource pour le stocker en mémoire sous forme de liste de chaînes de caractères :
using System;
using System.Net;
namespace Communication
{
/// <summary>
/// Démonstration d'une connexion à une ressource distante
/// </summary>
/// <remarks>L'équipe éducative d'OpenClassrooms</remarks>
public class PageDistante
{
/// <summary>
/// Se connecter à une ressource à partir d'une URL et afficher son contenu
/// </summary>
/// <param name="args">Pas utilisé dans cet exemple</param>
public static void Main(string[] args)
{
// Définir la représentation de la chaîne de caractères de l'URL à laquelle se connecter
string chaineUrl = DonneeUtilisateur.DemanderUneUrl();
Console.WriteLine(RecupererContenu(chaineUrl));
}
}
}
La première instruction de la méthode Main
est string chaineUrl = DonneeUtilisateur.DemanderUneUrl() ;
. Elle appelle la fonction DemanderUneUrl()
de la classe DonneeUtilisateur
et affecte la chaîne de caractères saisie par l'utilisateur à la variable chaineUrl
.
Voyons comment la méthode RecupererContenu
permet de récupérer le contenu en recevant cette instance comme argument.
Extrayez le contenu de la ressource
Dans la méthode RecupererContenu
, créons un nouveau WebClient
et téléchargeons le contenu de l' url
donnée dans une chaîne de caractères. Voici le code :
/// <summary>
/// Retourner le contenu de l'URL
/// </summary>
/// <param name="url">L'adresse Web de la page</param>
public static string RecupererContenu(string url)
{
string contenu = "";
try
{
using (WebClient webClient = new WebClient())
{
contenu = webClient.DownloadString(url);
}
}
catch(WebException e)
{
Console.WriteLine("Impossible d'établir une connexion - " + e.ToString());
}
return contenu;
}
Analysons la méthode RecupererContenu
:
On définit une variable
string
nomméecontenu
pour stocker la réponse de l'URL.L'instruction
using
englobe la création d'une instanceWebClient
nomméewebClient
. La classeWebClient
fournit des méthodes pour communiquer avec une URL.On appelle la méthode
DownloadString
dewebClient
en passant l'url
en tant que paramètre. On affecte le résultat de cet appel à la variablecontenu
.Si une exception
WebException
est levée, on écrit la description de l'erreur dans la console.Enfin, on retourne le
contenu
.
Exécutons à présent le programme et voyons comment il fonctionne.
Testez par vous-même !
Prêt à coder ? Pour accéder à l’exercice, suivez ce lien.
Générez un fichier texte
Dans la dernière section de ce chapitre, nous allons enregistrer le contenu de la ressource dans un fichier. Il nous faudra créer une autre classe qui utilisera notre classe PageDistante, et y ajouter la fonctionnalité.
La fonction Main est similaire au précédent programme. Il suffit d'ajouter un appel à une fonction qui écrira dans un fichier. Voici le code :
using System;
using System.Net;
using System.IO;
namespace Communication
{
/// <summary>
/// Démonstration d'une connexion à une ressource distante
/// </summary>
/// <remarks>L'équipe éducative d'OpenClassrooms</remarks>
public class PageDistante
{
/// <summary>
/// Se connecter à une ressource depuis une URL et écrire son contenu dans un fichier.
/// </summary>
/// <param name="args">pas utilisé dans cet exemple</param>
public static void Main(string[] args)
{
// Définir l'URL à laquelle se connecter
string chaineUrl = DonneeUtilisateur.DemanderUneUrl();
string contenu = RecupererContenu(chaineUrl);
try
{
EcrireFichier(contenu,"output.txt");
}
catch(IOException e)
{
Console.WriteLine("Impossible d'écrire dans le fichier - " + e.ToString());
}
}
}
}
L'écriture du fichier a lieu grâce à un appel à la méthode EcrireFichier
, uniquement si la connexion fonctionne. Voici le code :
/// <summary>
// Écrit le contenu d'une variable string dans un fichier.
/// </summary>
/// <param name="content">Le contenu à écrire dans le fichier</param>
// <param name="fileName">Le nom du fichier dans lequel écrire</param>
public static void EcrireFichier(string contenu, string nomFichier)
{
try
{
File.WriteAllText(nomFichier, contenu);
Console.WriteLine("Écriture terminée dans le fichier " + nomFichier);
}
catch(IOException e)
{
Console.WriteLine("Impossible d'écrire dans le fichier " + nomFichier);
}
}
La méthode File.WriteAllText
crée un nouveau fichier. Elle écrit dans le fichier, puis ferme le fichier. Si le fichier existe déjà, il sera remplacé.
Testez par vous-même !
Prêt à coder ? Pour accéder à l’exercice, suivez ce lien.
En résumé
Dans ce chapitre, vous avez appris les notions suivantes :
La communication réseau consiste à gérer une combinaison requête-réponse sur le réseau (généralement Internet), et fonctionne avec des URL.
En C#, les composants suivants sont utilisés pour mettre en œuvre la connexion :
URI
, qui fournit une représentation objet d'un identifiant de ressource uniforme, et un accès facile à ses parties.WebClient
, qui fournit des méthodes communes pour envoyer des données vers et depuis une ressource identifiée par un URI.File
, qui fournit des méthodes statiques pour créer, copier, supprimer, déplacer et ouvrir un fichier unique.