In deze zelfstudie laat ik je zien hoe je een Twitter-widget voor ASP.NET kunt schrijven in de vorm van een herbruikbare serverbesturing, compleet met leuke dingen zoals het automatisch omzetten van URL's in links en caching om laadtijden van pagina's te versnellen.
Om deze tutorial te volgen, heb je alleen Visual Studio nodig (je kunt MonoDevelop gebruiken als je geen Windows gebruikt, hoewel daar geen garanties zijn.) Als je niet voor contant geld wilt gaan voor de volledige versie van Visual Studio, kan de gratis Express-editie halen.
Je hebt ook kennis van C # 3.0 nodig, omdat deze tutorial gebruik maakt van een aantal van de nieuwere functies van de taal, zoals lambda-expressies en de var trefwoord.
ASP.NET bevat een handige functie die bekend staat als Server Controls. Dit zijn aangepaste tags die bedoeld zijn om ontwikkelaars te helpen hun code te structureren. Wanneer een pagina met een serverbesturingselement wordt aangevraagd, voert de runtime van ASP.NET de Render () methode en bevat de uitvoer op de laatste pagina.
Nadat u een nieuwe webtoepassing in Visual Studio hebt gemaakt, klikt u met de rechtermuisknop in Solution Explorer en voegt u een nieuw item toe aan de oplossing. Selecteer ASP.NET Server Control en geef het een naam. Hier, ik heb het gebeld Twidget.cs, maar je mag het gerust zeggen wat je maar wilt. Plak de volgende code in, en maak je geen zorgen als het allemaal een beetje vreemd lijkt - ik zal het binnenkort allemaal uitleggen.
systeem gebruiken; met behulp van System.Collections.Generic; met behulp van System.Linq; met behulp van System.Web; met behulp van System.Web.UI; met behulp van System.Web.Script.Serialization; met behulp van System.Net; naamruimte WebApplication1 public class Twidget: Control public string Account get; vast te stellen; public int Tweets get; vast te stellen; beschermde override void Render (HtmlTextWriter writer) writer.Write ("
Dit is ongeveer net zo eenvoudig als je kunt krijgen voor een Twitter-widget. Dit is hoe het werkt:
Wanneer een gebruiker een pagina opvraagt met dit besturingselement erop, de Render () methode wordt uitgevoerd met een HtmlTextWriter geslaagd als een parameter. Het schrijft de tag en voert vervolgens een lus in die elke tweet als een lijstitem afdrukt. De magie hier gebeurt in de GetTweets () methode. Merk op hoe we de gebruiken Nemen() uitbreidingsmethode om ervoor te zorgen dat we alleen het aantal tweets afdrukken dat ons wordt gevraagd.
Zodra de uitvoering is doorgegeven aan de GetTweets () methode, we stellen een List> string< om onze tweets te houden en een JavaScriptSerializer om de JSON van de Twitter API-servers te ontleden. De verklaring op regels 31 - 34 (opgesplitst voor leesbaarheid) haalt de gebruikerstijdlijn op in JSON-formaat en deserialiseert vervolgens in .NET-typen waarmee we kunnen werken. Op regel 36 doorlopen we alle tweets en voegen ze één voor één toe aan de tweet-lijst. We moeten handmatig casten x [ "tekst"] naar een draad omdat we het deserialiseerden als een voorwerp. We moesten dit doen, omdat de door de Twitter API geretourneerde JSON een smorgasboard van verschillende typen gebruikt - wat prima is voor JavaScript, maar een beetje lastig met C #.
Nu hebben we de code voor onze Twitter-widget; laten we het gebruiken! Open je default.aspx pagina (of op welke pagina u dit ook wilt gebruiken) en plaats de volgende code direct na de <%@ Page %> richtlijn:
<%@ Register TagPrefix="widgets" Namespace="WebApplication1" Assembly="WebApplication1" %>
Voel je vrij om de TagPrefix naar wat je maar wilt, maar zorg ervoor dat het namespace kenmerk is correct ingesteld op de naamruimte waarin u de widgetcode hebt geplaatst en zorgt ervoor dat de bijeenkomst kenmerk is ingesteld op de naam van uw webtoepassing (in ons geval, WebApplication1).
Nadat u het juiste tagvoorvoegsel hebt geregistreerd (en u moet dit doen voor elke pagina waarop u het besturingselement wilt gebruiken), kunt u het gaan gebruiken. Plak de volgende code ergens op uw pagina en nogmaals, voel je vrij om de attributen te veranderen in wat je maar wilt:
Als je alles goed hebt gedaan, zou je een soortgelijke pagina moeten zien als je je webtoepassing draait:
Je moet toegeven dat de controle die we op dit moment hebben vrij rudimentair is. Het hoeft niet zo te zijn, dus laten we het een beetje opfrissen door van URL's mooie, klikbare links voor uw bezoekers te maken.
Zoek de foreach-lus in de Render () methode en het volledig schrappen. Vervang het hiermee:
// u moet deze gebruikende instructie bovenaan in het bestand toevoegen: using System.Text.RegularExpressions; foreach (var t in GetTweets (). Take (Tweets)) string s = Regex.Replace (HttpUtility.HtmlEncode (t), @ "[az] +: // [^ \ s] +", x => " "+ x.Value +" ", RegexOptions.Compiled | RegexOptions.IgnoreCase); writer.Write ("
Het is allemaal ongeveer dezelfde code, behalve de gigantische oproep tot Regex.Replace () op regel 6. Ik zal uitleggen wat dit doet.
De eerste parameter is de invoer of de tekenreeks waaraan de Regex werkt. In dit geval is het alleen de tweet-tekst nadat deze is doorgegeven HttpUtility.HtmlEncode () dus we worden niet het slachtoffer van een vicieuze XSS-aanval. De invoer wordt vervolgens vergeleken met de tweede parameter, een reguliere expressie die is ontworpen om overeen te komen met een URL.
De derde parameter is waar het een beetje mee te maken krijgt. Dit is een lambda-uitdrukking, een nieuwe functie voor C # 3. Het is eigenlijk een heel korte manier om een methode als deze te schrijven:
public static string SomeFunction (Match x) return "" + x.Value + "";
Het enige dat het doet is de URL omwikkelen met een tag, waarvan alle aanhalingstekens in de URL worden vervangen door de HTML-entiteit ", wat helpt bij het voorkomen van XSS-aanvallen. De vierde en laatste parameter is slechts een OFsamengevoegd paar vlaggen die de manier aanpassen waarop onze regex zich gedraagt.
De uitvoer van de besturing na het maken van deze aanpassing lijkt enigszins op de onderstaande schermafbeelding.
Er is een groot probleem met de code die ik je hierboven heb gegeven, en dat is dat het de reactie van de Twitter API niet in de cache opslaat. Dit betekent dat elke keer dat iemand uw pagina laadt, de server een verzoek moet indienen bij de Twitter API en moet wachten op een reactie. Dit kan de laadtijd van je pagina drastisch vertragen en kan je zelfs nog kwetsbaarder maken voor een Denial of Service-aanval. Gelukkig kunnen we dit allemaal omzeilen door een cache te implementeren.
Hoewel de basisstructuur van de besturingscode nog steeds aanwezig is na het implementeren van cachegeheugen, zijn er te veel kleine wijzigingen in de lijst, dus ik zal u de volledige bron geven en vervolgens - zoals gewoonlijk - uitleggen hoe het werkt.
systeem gebruiken; met behulp van System.Collections.Generic; met behulp van System.Linq; met behulp van System.Web; met behulp van System.Web.UI; met behulp van System.Web.Script.Serialization; met behulp van System.Net; met behulp van System.Threading; using System.Text.RegularExpressions; naamruimte WebApplication1 public class Twidget: Control public string Account get; vast te stellen; public int Tweets get; vast te stellen; public int CacheTTL get; vast te stellen; static Dictionary>> Cache = nieuw woordenboek >> (); beschermde override void Render (HtmlTextWriter writer) writer.Write (" "); foreach (var t in GetTweets (). Take (Tweets)) string s = Regex.Replace (HttpUtility.HtmlEncode (t), @" [az] +: // [^ \ s] + ", x => "" + x.Value + "", RegexOptions.Compiled | RegexOptions.IgnoreCase); writer.Write ("
"); openbare lijst- 0
", s); writer.Write ("GetTweets () if (! Cache.Keys.Contains (Account) || (DateTime.Now - Cache [Account] .Time) .TotalSeconds> CacheTTL) new Thread (Update) .Start (Account); als (! Cache.Keys.Contains (Account)) een nieuwe lijst retourneert (); return Cache [Account] .Data; public static void Update (object acc) try string Account = (string) acc; var ls = nieuwe lijst (); var jss = nieuwe JavaScriptSerializer (); var d = jss.Deserialize >> (nieuwe WebClient () .DownloadString ("http://api.twitter.com/1/statuses/user_timeline.json?screen_name=" + Account)); foreach (var x in d) ls.Add ((string) x ["text"]); if (! Cache.Keys.Contains (Account)) Cache.Add (Account, nieuwe Cachedata
> ()); Cache [Account] .Data = ls; catch (Uitzondering) class CachedData
public DateTime Time get; privé set; T-gegevens; openbare T-gegevens krijg retourgegevens; set Time = DateTime.Now; data = waarde;
Zoals u kunt zien, de Render () methode blijft ongewijzigd, maar er zijn overal behoorlijk drastische veranderingen. We hebben de GetTweets () methode, een nieuwe eigenschap toegevoegd (CacheTTL), een privé statisch veld toegevoegd (Cache), en er is zelfs een hele nieuwe klas - CachedData.
De GetTweets () methode is niet langer verantwoordelijk voor het praten met de API. In plaats daarvan worden alleen de gegevens geretourneerd die al in de cache zitten. Als het detecteert dat het aangevraagde Twitter-account nog niet in de cache is opgeslagen, of verouderd is (u kunt opgeven hoe lang het duurt voordat de cache vervalt in de CacheTTL attribuut van de besturing), zal het een aparte thread uitbrengen om de tweet-cache asynchroon bij te werken. Merk op dat het hele lichaam van de Bijwerken() methode is ingesloten in een try / catch-blok, omdat hoewel een uitzondering in de paginering alleen een foutmelding voor de gebruiker weergeeft, als een uitzondering in een andere thread voorkomt, deze helemaal terug de stapel afwikkelt en uiteindelijk de hele reeks crasht werkproces verantwoordelijk voor het bedienen van uw webapplicatie.
De tweet-cache is geïmplementeerd als een Woordenboek
U kunt de volgende code op uw pagina gebruiken om deze caching-versie van de widget te gebruiken. Merk op dat de nieuwe CacheTTL attribuut bepaalt de expiratie (in seconden) van de tweet-cache.
Ik hoop dat deze tutorial je niet alleen heeft geleerd hoe je een Twitter-widget maakt, maar je ook inzicht heeft gegeven in hoe serverbesturingssystemen werken en wat je best practices zijn wanneer je gegevens uit externe bronnen 'verzamelt'. Ik realiseer me dat de browseruitgang van deze besturing niet bepaald de mooiste is, maar ik vond dat het stylen en er mooi uitzien buiten het bereik van het artikel viel en daarom als een oefening voor de lezer is achtergelaten. Bedankt voor het lezen! Aarzel niet om eventuele vragen te stellen in de comments hieronder.