Dans ce tutoriel, je vais vous expliquer comment écrire un widget Twitter pour ASP.NET sous la forme d'un contrôle de serveur réutilisable, avec des fonctionnalités utiles telles que la conversion automatique des URL en liens et la mise en cache pour accélérer les temps de chargement des pages..
Pour suivre ce didacticiel, tout ce dont vous avez besoin est Visual Studio (vous pouvez utiliser MonoDevelop si vous n’êtes pas sous Windows, bien qu’il n’y ait aucune garantie.) Si vous ne voulez pas débourser d’argent pour la version complète de Visual Studio, vous peut saisir l'édition Express gratuite.
Vous aurez également besoin de connaissances en C # 3.0, car ce didacticiel utilise certaines des nouvelles fonctionnalités du langage, telles que les expressions lambda et la var mot-clé.
ASP.NET inclut une fonctionnalité pratique appelée Contrôles de serveur. Ces balises personnalisées visent à aider les développeurs à structurer leur code. Lorsqu'une page utilisant un contrôle serveur est demandée, le runtime ASP.NET exécute le Rendre() méthode et inclut la sortie dans la dernière page.
Une fois que vous avez créé une nouvelle application Web dans Visual Studio, cliquez avec le bouton droit de la souris dans l'explorateur de solutions et ajoutez un nouvel élément à la solution. Sélectionnez Contrôle de serveur ASP.NET et nommez-le. Ici, je l'ai appelé Twidget.cs, mais vous pouvez l'appeler comme bon vous semble. Collez le code suivant, et ne vous inquiétez pas si cela semble un peu étranger - je vous expliquerai tout cela sous peu.
en utilisant le système; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.Script.Serialization; using System.Net; espace de noms WebApplication1 public class Twidget: Control chaîne publique Account get; ensemble; public int Tweets get; ensemble; protégé annule le rendu Render (HtmlTextWriter writer) writer.Write ("
C’est aussi simple que vous pouvez obtenir pour un widget Twitter. Voici comment ça fonctionne:
Lorsqu'un utilisateur demande une page avec ce contrôle, le Rendre() méthode est exécutée avec un HtmlTextWriter passé en paramètre. Il écrit le tag, puis entre dans une boucle qui affiche chaque tweet en tant qu’élément de la liste. La magie se passe ici dans le GetTweets () méthode. Notez comment nous utilisons le Prendre() méthode d'extension pour nous assurer que nous imprimons uniquement la quantité de tweets que l'on nous a demandé de.
Une fois que l'exécution passe au GetTweets () méthode, nous configurons un Liste> chaîne< tenir nos tweets et un JavaScriptSerializer analyser le JSON des serveurs API Twitter. L’énoncé des lignes 31 à 34 (fractionné pour des raisons de lisibilité) rappelle le scénario de l’utilisateur au format JSON, puis se désérialise en types .NET avec lesquels nous pouvons travailler. Sur la ligne 36, nous parcourons tous les tweets et les ajoutons un par un à la liste de tweets. Nous devons lancer manuellement x ["texte"] à un chaîne parce que nous l'avons désérialisé en tant que objet. Nous devions faire cela, car le JSON renvoyé par l'API Twitter utilise un même type de tableau de bord - ce qui est bien pour JavaScript, mais un peu délicat avec C #.
Nous avons maintenant le code de notre widget Twitter; mettons-le à utiliser! Ouvrez votre Default.aspx page (ou quelle que soit la page où vous souhaitez l'utiliser) et mettez le code suivant immédiatement après la <%@ Page %> directif:
<%@ Register TagPrefix="widgets" Namespace="WebApplication1" Assembly="WebApplication1" %>
N'hésitez pas à changer le TagPrefix à ce que vous voulez, mais assurez-vous que le Espace de noms L’attribut est correctement défini sur l’espace de nom dans lequel vous avez placé le code du widget et assurez-vous que Assemblée attribut est défini sur le nom de votre application Web (dans notre cas, WebApplication1).
Une fois que vous avez enregistré le préfixe de balise approprié (et que vous devez le faire pour chaque page sur laquelle vous souhaitez utiliser le contrôle), vous pouvez commencer à l'utiliser. Collez le code suivant quelque part dans votre page et, encore une fois, n'hésitez pas à changer les attributs en ce que vous voulez:
Si vous avez tout fait correctement, vous devriez voir une page semblable à celle-ci lorsque vous exécutez votre application Web:
Vous devez admettre que le contrôle que nous avons pour le moment est assez rudimentaire. Il n'est pas nécessaire que ce soit le cas. Modifions-le un peu en transformant les URL en liens conviviaux pour vos visiteurs..
Trouver la boucle foreach dans le Rendre() méthode et la ferraille complètement. Remplacez-le par ceci:
// vous devrez ajouter cette directive using en haut du fichier: using System.Text.RegularExpressions; foreach (var dans GetTweets (). Take (Tweets)) chaîne s = Regex.Replace (HttpUtility.HtmlEncode (t), @ "[az] +: // [^ \ s] +", x => " "+ x.Value +" ", RegexOptions.Compiled | RegexOptions.IgnoreCase); writer.Write ("
C'est à peu près le même code, à l'exception de l'énorme appel à Regex.Replace () sur la ligne 6. Je vais expliquer ce que cela fait.
Le premier paramètre est l'entrée ou la chaîne sur laquelle Regex fonctionne. Dans ce cas, c'est juste le texte du tweet après avoir été passé à travers HttpUtility.HtmlEncode () Nous ne sommes donc pas victimes d'une attaque XSS vicieuse. L'entrée est ensuite comparée au deuxième paramètre qui est une expression régulière conçue pour correspondre à une URL..
Le troisième paramètre est l'endroit où cela devient un peu impliqué. C'est une expression lambda, une nouveauté de C # 3. C'est en gros une manière très courte d'écrire une méthode comme celle-ci:
chaîne publique statique SomeFunction (Match x) return "" + x.Value + "";
Tout ce qu’il fait est d’envelopper l’URL avec un balise dont tous les guillemets de l'URL sont remplacés par l'entité HTML ", qui aide à prévenir les attaques XSS. Le quatrième et dernier paramètre est juste un OUed ensemble paire de drapeaux ajustant la façon dont notre regex se comporte.
La sortie du contrôle après avoir effectué cet ajustement est un peu similaire à la capture d'écran ci-dessous..
Le code que je vous ai donné ci-dessus pose un gros problème: il ne met pas en cache la réponse de l'API Twitter. Cela signifie que chaque fois que quelqu'un charge votre page, le serveur doit adresser une requête à l'API Twitter et attendre une réponse. Cela peut ralentir considérablement le temps de chargement de votre page et vous rendre encore plus vulnérable aux attaques par déni de service. Heureusement, nous pouvons contourner tout cela en implémentant un cache.
Bien que la structure de base du code du contrôle reste après la mise en cache, il y a trop de petites modifications à lister. Je vais donc vous donner le code source complet, puis, comme d'habitude, expliquer son fonctionnement..
en utilisant le système; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.Script.Serialization; using System.Net; using System.Threading; using System.Text.RegularExpressions; espace de noms WebApplication1 public class Twidget: Control chaîne publique Account get; ensemble; public int Tweets get; ensemble; public int CacheTTL get; ensemble; dictionnaire statique>> Cache = nouveau dictionnaire >> (); protégé annule le rendu Render (HtmlTextWriter writer) writer.Write (" "); foreach (var dans GetTweets (). Take (Tweets)) chaîne s = Regex.Replace (HttpUtility.HtmlEncode (t), @" [az] +: // [^ \ s] + ", x => "" + x.Value + "", RegexOptions.Compiled | RegexOptions.IgnoreCase); writer.Write ("
"); liste publique- 0
", s); writer.Write ("GetTweets () if (! Cache.Keys.Contains (Account) || (DateTime.Now - Cache [Account] .Time) .TotalSeconds> CacheTTL) nouveau thread (mise à jour) .Start (Account); if (! Cache.Keys.Contains (Account)) renvoie la nouvelle liste (); retour Cache [Compte] .Data; public static void Mise à jour (object acc) try string Account = (string) acc; var ls = nouvelle liste (); var jss = new JavaScriptSerializer (); var d = jss.Deserialize >> (new WebClient () .DownloadString ("http://api.twitter.com/1/statuses/user_timeline.json?screen_name=" + compte)); foreach (var x dans d) ls.Add ((chaîne) x ["text"]); if (! Cache.Keys.Contains (Account)) Cache.Add (Compte, nouveau CachedData
> ()); Cache [Compte] .Data = ls; catch (Exception) classe CachedData
public DateTime Time get; ensemble privé; T données; public T Data get return data; set Time = DateTime.Now; données = valeur;
Comme vous pouvez le voir, le Rendre() La méthode reste inchangée, mais il y a des changements assez drastiques partout ailleurs. Nous avons changé le GetTweets () méthode, ajouté une nouvelle propriété (CacheTTL), ajouté un champ statique privé (Cache), et il y a même une toute nouvelle classe - CachedData.
le GetTweets () méthode n’est plus responsable de la communication avec l’API. Au lieu de cela, il renvoie simplement les données déjà présentes dans le cache. S'il détecte que le compte Twitter demandé n'a pas encore été mis en cache ou qu'il est obsolète (vous pouvez spécifier le temps qu'il faut pour que le cache expire dans l'espace réservé). CacheTTL attribut du contrôle), il créera un thread séparé pour mettre à jour de manière asynchrone le cache tweet. Notez que tout le corps de la Mettre à jour() La méthode est enfermée dans un bloc try / catch, car même si une exception dans le fil de page affiche simplement un message d'erreur à l'utilisateur, si une exception se produit dans un autre fil de discussion, elle se déroulera jusqu'à la pile de sauvegarde et finira par planter toute la pile. processus de travail chargé de servir votre application Web.
Le cache tweet est implémenté en tant que dictionnaire
Vous pouvez utiliser le code suivant dans votre page pour utiliser cette version de mise en cache du widget. Notez que la nouvelle CacheTTL attribut définit l'expiration (en secondes) du cache tweet.
J'espère que ce didacticiel vous a non seulement appris à créer un widget Twitter, mais qu'il vous a également éclairé sur le fonctionnement des contrôles de serveur, ainsi que sur les meilleures pratiques pour "écraser" des données provenant de sources externes. Je me rends compte que la sortie du navigateur de ce contrôle n’est pas exactement la plus jolie, mais j’ai eu le sentiment que le styliser et le rendre joli était en dehors du cadre de l’article et a donc été laissé comme un exercice pour le lecteur. Merci d'avoir lu! N'hésitez pas à poser toutes les questions que vous pourriez avoir dans la section commentaires ci-dessous.