Användning av WebResources i Asp .net 1.1
Förord
Snabb åtkomst; mycket data och få filer; är något vi eftersträvar när vi bygger våra applikationer, särskilt nu när allt bara blir mer och mer globalt där Internet spelar en allt större roll för våra applikationer. Förutom prestanda så är säkerhet ett måste. Problemet uppstår när vi vill kombinera dem båda. Vi från Nsquared2 har bestämt oss för att bygga ett litet ramverk vid sidan av Microsoft .Net ramverk, som dels skall ge lösning på dessa två problem med även ge stöd för snabbare och flexiblare utveckling. Vi har tidigare publicerat en artikel om templates
Nsquared2 Web Resurs.
En webapplikation brukar som bekant ha en hel del lösa filer, javascript filer (js), bilder, texter, Stil mallar m.m. Dessa filer brukar oftast inte förändras när en applikation är klar. Du återanvänder din js fil, du hämtar dina bilder och länkar in din stilmall utan problem. Dock kan en rad problem uppstå, exempelvis så har du flera filer att hålla reda på, du har kanske flera applikationer på samma server som vill nyttja gemensamma filer, det kan uppstå problem med versionering av filer och du kan även få prestandaproblem i de fall då länkade filer faktiskt inte läggs i en cache. Allt detta kan du enkelt lösa med We resursen. Vad det handlar om är att du bakar in dina filer i någon assembly för att sedan enkelt plocka ut dem och klistra in dem på din webb applikation. På så vis ökar du prestanda, de läggs i en cache, säkerheten ökar då du inte behöver vara orolig att du glömt installera en fil eller att någon kunnat ändra den, versionshantering ingår med automatik, du får färre antal filer att hålla reda på, och det blir det enlkelt att dela resurserserna över alla dina applikationer genom att lägga dina filer i en assembly som placeras i GACen, (Global Assembly Cachen).
Låt oss ta en titt på det hela.
I vår senaste version av Nsqaured2.Web (som du kan ta hem här!) hittar du en del nya klasser.
AssemblyResourceLoader
Resource
WebResourceAttribute
och asp .net filen Webresource.aspx
Webresource.aspx
WebResource.aspx är huvud filen för att få ut den inbakade datan.(resureserna, så som script, stilmallar, bilder m.m.) Det finns två olika sätt att plocka ut datan:
Sträng (Url) | Beskrivning | |
webresource.aspx?a=pWebTest&r=box.gif&t=10 | Privat assembly | |
WebResource.aspx?a=fNsqaured2.Web,Version=1.1.1503.30672,Culture=neutral, ublicKeyToken=b03f5f7f11d50a3a&r=box.gif&t=127210753474843750 | Strong named assembly |
Vi har gjort på detta vis för att du förutom privata assemblies också skall kunna använda globala assemblies (url 2). Delade resruser för andra applikationer på din server.
Vårt anrop består av tre olika querystring parametrar.
Qureystring variabel | Beskrivning | |
a | Står för Assembly namnet | |
r | Namnet på vår resurs | |
t | Tidstämpel för cache hanteringens skull. |
Den första är a som står för assembly, här skriver vi helt enkelt namnet på den assembly vi vill ta resurser från. r står för resource, det är den inbakade resursen vi vill plocka ut. Sedan har vi t som är lite speciell, det är vår tidstämpel; vi skapar denna genom att ta det datum då assemblyn blev skapad och plockar ut ett tal baserat på 100-nanosekunders intervall från 12:00 Jan 0001. Tidstämpeln används endast för vår cache hanterign och versionering. Alla resurser som hämtas kommer att läggs i en evig output cache baserat på de tre parametrarna. Om en ny version av assemblyn skulle skapas kommer den att få en ny tidstämpel och cacheas om igen.
Om du tar en noga titt på de olika sätten att skriva vårt anrop på så kan du lägga märke till p samt f framför assembly namnet. Låt oss ta en titt på varför vi har gjort så.
p och f prefixen.
I vår queryvariabel a har vi ett litet prefix framför assembly namnet. f samt p.
Prefix | Beskrivning | |
f | Fullt assembly namn | |
p | Publikt Assembly namn |
För att kunna ladda in delade assemlibes (GAC) så måste vi ha med en hel del andra uppgifter än bara assemblynamnet, alltså dess fulla namn.
Nsqaured2.Web,Version=1.1.1503.30672,Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
Det kanske kan tyckas konstigt att vi inte har ett enhetligt sätt att anropa vår datan på, exempelvis alltid basera assembly namnet på dess fulla namn. Vi har valt att ha dessa prefix av prestandaskäl. Du kanske undrar hur? Låt mig ge en kort förklaring. Låt säga att du skrivit följande tag
”<img src=”images/icons/box.gif” style=”BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid">”
Denna tag är hela 162 tecken, vilket kommer att skickas över till klienten. Genom att nyttja WebResource.aspx så blir samma resultat 127 tecken vilket ger en minskning på 35 tecken.
Vår motsvarande sträng skulle kunna se ut på följande sätt:
<img src=” WebResource.aspx?a=pNsquared2.Web&r=box.gif&t=0” style=”WebResource.aspx?a=pNsquared2.Web&r=DefautStyle.css&t=0” />
Tio sådana anrop och du skulle spara hela 350 bytes, vilket är rätt mycket i kritiska applikationer. Det hela baseras ju självklart på en massa faktorer, ibland kan ju vår sträng bli längre, men i genomsnitt kommer mindre tecken att skickas över nätet.
Hur det hela fungerar!
1. En användare går mot default.aspx.
2. Där man angett en <img> tag vars source är en web resurs.
3. WebResource.aspx med dess parametrar körs. (2)
4. AssemblyResourceLoader (Vår HttpHandler) Tar emot begäran
5. Läser in vår assembly (Nsqaured2.Web
6. Plockar ut Box.gif, vår resurs
7. Granskar vilken contenttype den består av och ritar då ut vår box som en gif till klienten.
Resource klassen
Det är ju inte så lätt att hålla reda på version, PublicKey token samt tidstämpeln. För att underlätta detta hittar du en metod under medföljande Resource klass som heter WebResourceUrl(...), denna metod hjälper dig att generera en url baserat på den information du skickar in. WebResourceUrl tar emot en type och namnet på den resurs du vill komma åt. Image1.ImageUrl = Resource.WebResourceUrl(typeof(DinTyp),”DefaultStyle.css”);
* Varför denna metod tar emot en type och inte en assembly vilket skulle vara ett mer riktigt sättet beror på att det skall hålla samma signatur som andra klasser. Vi ville göra vår implementation kompatibel med den i Asp .Net 2.0.
Vad vi nu får ut av vår syntax är följande sträng.
<img src=”WebResource.aspx?a=pNsquared2.Web&r=DefautStyle.css&t=127210753474843750” id=”Image1”/>
AssemblyResourceLoader klassen
Denna klass är själva hanteringen av resurserna. Den kör som en HTTPHandler och ärver IHttphandler. För att få den att fungera måste du registrera den i web.config. <httpHandlers>
<add verb="GET" path="WebResource.aspx" type="Nsquared2.Web.AssemblyResourceLoader,Nsquared2.Web"/>
</httpHandlers>
Vad vi gör här är att vi talar om för Asp .Net runtime att köra vår HttpHandler då du går mot WebResopurce.aspx. Du placerar din WebResource.aspx fil i din webbapplikation.
För att webbläsaren skall förstå vad det är för typ av data du vill strömma ut så behöver AssemblyResourceLoader ytterligare information än det du har i websresource.aspx urlen. Vad du måste göra är att säga åt Assemblyn som innehåller din resurs vilken contenttype resrusen består av. Detta ställer du in med hjälp av WebResourceAttribute.
[assembly: WebResourceAttribute("box.gif","image/gif")]
För varje resurs du vill använda måste lägga till denna beskrivning i din assembly, bästa platsen är i assemblyinfo.cs filen. Orsaken att vi valt att göra så är främst av säkerhetsskäl. Finns det en resurs i vår assembly som vi inte vill att någon skall komma åt så anger vi ingen WebResourceAttribute och vid anropsförsök kommer webresource.apsx att slänga ut sig ett exception för att den inte vet vilken contenttype den skall avnända sig av. Det kan även vara så att du som utvecklare inte alls vill strömma ut box.gif som gif utan som text då kan du bara sätta din gif till text contentype. Låt oss ta en närmare titt på WebResourceAttribute.
WebResourceAttribute Klassen.
Denna klass tar emot två sträng parametrar. webResosurce samt contentType.
Till webResource parametern anger du det resursnamn din embeded resurs i assemblyn har. Sedan till contentType parametern anger du den contenttype du vill använda dig av för just denna resurs. Som i ovan exempel, där vi vill att box.gif skall strömma ut som gif. (image/gif). Om din resurs ligger i en undermapp måste du lägga till mappens namn framför resursnamnet. Exempelvis images/box.gif då blir resursnamnet images.box.gif
Enklare än så kan det knappast bli. För att du skall få en bättreförståelse så följer här en liten övning.
Download
Ladda ner senaste versionen av Nsquared2.Web
Exempel
Om du vill testa ett exempel hittar du ett webresource exempel under Default8.aspx i vår zip fil. För er som själva vill testa att implementera denna hantering följer här en liten övning.
Övning
För att du skall få en bättre kontroll på det hela följer här en enkel övning, där vi tänkte lägga till en gif bild samt ett JavaScript. Först måste du ladda ner vår senaste version av Nsquared2.Web om du inte redan gjort det. 1. Starta ett nytt webprojekt i VisualStudio .Net (Döp det till HelloResourceTest)
2. Öppna web.config och lägg till följande mellan <system.web> och </system.web> taggen.
<httpHandlers>
<add verb="GET" path="WebResource.aspx" type="Nsquared2.Web.AssemblyResourceLoader,Nsquared2.Web"/>
</httpHandlers>
3. Efter detta så lägger du till en referens till vår dll.
4. Välj lägg till ny fil och välj någon bildfil du har liggande. I vårt fall Box.gif.
I Properties för filen sätter du den till embeded resource. Du kan om du vill skapa en mapp och lägga dina filer där. Var bara noga med att du då måste ange detta när du anger ditt Web Resursens namn, exempelvis <folder>.Box.gif
5.I AssemblyInfo.css lägger du till följande information:
[assembly: WebResourceAttribute("box.gif","image/gif")]
Om vi hade lagt filen i en mapp skulle du även här vara tvungen att skriva ”<folder>.” före box.gif. Låt säga att vi har en mapp som heter images dät vi lägger vår fil, då skulle namnet till resrusfilen bli, images.Box.gif
6.Nu lägger du till en textfil. Lägg in följande script kod.
<script>alert(’Hello World’)</script>
Byt namn till HelloScript.js och sätt även denna som embeden resource.
7.I AssemblyInfo.sc skriver du nu
[assembly: WebResourceAttribute("HelloScript.js","text/javascript")]
8. Lägg nu in WebResource.aspx i din root map för web projektet.
9. På htmlsidan lägger du nu till:
<img src=”WebResource.aspx?a=pHelloResourceTest&r=box.gif&t=0”>
OBS! Glöm inte ange <folder.> innan namnet på filen ifall du la den i en undermapp.
10. Sedan lägger du till följande:
<script language="javascript" src="WebResource.aspx?a=pHelloResourceTest&r=HelloScript.js&t=0" type="text/javascript"></script>
11. Kompilera och kör. Du kommer då först få upp en message box med texten Hello World! och sedan få se din bild, i vårt fall en Box.
Sammanfattning.
I denna artikel har vi gått genom hur du enkelt med några få rader kod kan optimera prestandan samt öka säkerheten genom att lagra resursdata i dina assemblies. Vi har gått genom syntaxen, dess parametrar och slutligen haft en övning där du själv fick känna på hur det hela fungerar. Vi hoppas ni får stor nytta av våra Web resurshantering och kommande Api:er från Nsquared2. Lycka till!
Mvh Johan Normén
Obs! Detta dokument innehåller fel i img-taggar, en sluttagg saknas. Vänligen korrigera dessa!
0 Kommentarer