Uus imedieet –20kg!

juuli 31, 2009 kirjutas neemevool

Vabandan kohe esimese lausega. Jah, –20kg on õige. Kuid mingit imet siin ei ole. Pigem tahaksin kirja panna oma lõpliku arvamuse kõikidest imedieetidest ja kaalujälgimisest peale seda, kui ilma erilise nähtava tahte- või jõupingutuseta saavutasin languse 113kg-lt 93 kilole. Ja mitte ainult. Samal ajal suurendasin oma füüsilisi võimeid märgatavalt (nii ise tehtavate kui laboratoorsete mõõtmistega tõestatult).

Mõnele võib alljärgnev ehk olla hirmutav, mõnele aga annab ehk paremaid näpunäiteid, kuna olen nüüd selle kõik ise läbi teinud.

Lähtekoht

Oma füüsilisest ja dietoloogilisest taustast. Olen hetkel 36 aastat vana, kaks aastat tagasi olin oma elu kaalu “tipul” – 113 kg. Pikkus on 178 cm. Alates lapseeast kuni põhikooli lõpuni olin üle keskmise kaaluga, kuid siiski peab mainima, et vägagi liikuv. Väga palju aega veetsin väljas, sestap väitis Vomaxis koormustesti teinud professor, et ilmselt sellest ka keskmise täiskasvanuga võrreldes 130% kopsumaht. Pärilikult tugev ja väga koormustaluv süda – maksimaalne treeningpulss 188. Aga see ei ole antud juhul siiski määrav. Keskkoolis hakkasin tõsisemalt treenima, siis lubas esimest korda ENSV ajaloos haridusministeerium ka kehalise kasvatuse kavasid diferentseerida. Valida sai jõusaali, üldkehalise ja kergejõustiku vahel. Ei ole vaja kaks korda arvata – muidugi valisin jõusaali. Sellest peale algas esimene vormi saavutamine. Keskkooli lõpuks oli kõik normis. Ülikooli 2. kursusest alates alustasin aga kooli kõrvalt tööd ja sellest ajast hakkasid prioriteedid segi minema – liikumisi ja trenne jäi ära, spordisaalide külastused olid järjest kaootilisemad. Muidugi arvasin ma kuni 113 kg-ni et ma olen heas vormis – tugev eesti mees, vööümbermõõt 112 ei ole ju õnnetus. Pükse veel poest leidis.

Siiski, päris rahul ma ei olnud ja illusioonides ei elanud. Püüdsin ikka midagi ette võtta. Käisin jõusaalis – mehelik koht ju. Muide, mehed kes te arvate, et jõusaalis pingutavad kangelased. Anaeroobset kõrge pulsi juures tekkivat pinget on palju raskem taluda kui jõusaalis rassida! Sestap niiväga palju ma rattaga või joostes ei pingutanud ka.

Vomaxis mõõtsin ära enda füüsilised näitajad koormuse all tehtavas hapnikutarbimise testis.

Kaal: 112,5 kg

Pikkus: 178 cm

Max pulss: 186

Pulss istudes: 78

Vererõhk: 90/150

Vererõhk max koormuse ajal: 200

Taastumine: 4-5 min

Max hapnikutarbmine ml/kg: 32 (halb)

Jalgade jõud: 275W (hea)

Rasvaprotsent: 27%

Dieedid

Lühidalt võib dieedid jagada kaheks – kehale või rahakotile hävitavalt mõjuvaks. Mõned neist on muidugi ka mõlemat korraga. Kõige ohutumad on lihtsalt rahakotile mõjuvad dieedid, neid leiab enamasti läikivatest ajakirjadest. Nende praktiliselt ainus väärtus on see, et kõiki vajalikke koostisosi hankides kulutate märkimisväärsel hulgal kaloreid. Peale kolossaalse rahakulu on neil aga teine halb omadus – nad tekitavad näilise rahulolu – ma ju tegelen dieediga ja võtan midagi ette. Kuid alati lõppeb kõik pohmelusega – mingit praktilist ja väga nähtavat mõju ei ole. Peamine põhjus on, et õgid ka seda dieettoitu ikkagi meeletus koguses – söömisharjumused jäävad samaks. Proovisin mõnesid selliseid dieete, kuid lõpetasin peamiselt seetõttu, et kogu selle menüü valmistamine oli üks paras jahmerdamine.

Teine suur kategooria on tervisele kahjulikud dieedid. Siia alla kuuluvad kõik dieedid, mida serveeritakse kui imet. Söö toitaineid eraldi dieedid, valgudieedid, rasvadieedid, veedieedid kuni radikaalsed 900kcal dieedid jne. Laias laastus ajavad sellised dieedid kas keha paanikasse (drastiliselt madalakalorilised) või siis rikuvad normaalse ainevahetuse (ühekülgsed dieedid). Erinevalt vaid rahakotile mõjuvatest dieetidest on neil muidugi mingi mõju olemas – teatud määrani või siis teatud tervisliku seisundini. Enamasti võib aga unustada sportimise ja aktiivse elu, raskemad variandid tagavad halval juhul vaid vegeteerimise sarnase letargia. Nende puhul mul kahjuks mingit isiklikku kogemust ei ole, kuna omades siiski mingit teadmist füsioloogiast, toitumisest ja ainevahetusest vältisin neid kategooriliselt.

-20kg?

Mida aga siis peale seda targutamist teha? Kui ma ei oleks ilma imedieetideta saavutanud –20kg, siis ilmselgelt ei julgeks ma dieetide kohalt sõna võtta. Enne alustamist seadsin lisaks aga tingimused:

  • füüsiline vorm peab paranema kõikides parameetrites. Ma pean peale programmi olema tugevam (ühekordselt tõstetavate raskuste mõttes), vastupidavam (jõuvastupidavus), kiirem (rattasõit, sõude-ergomeeter). Kuna ma ei kavatse tegelda tippspordi tasemel, siis ei tohiks muidu vastuoluliste näitajate arendamine võimatu olla.
  • parema tervisega. Ei tahaks lõpetada vigastuste hinnaga. Samuti peaks paranema mitmed näitajad mida mõõdetakse laboris – maksimaalne hapnikutarbimine, vererõhu näitajad, südame töö jms.

Asja võti

Kui teha kohe kokkuvõte, siis tuleb öelda, et asja tuumaks on elustiili muutus. Mitte mingi kampaania “homsest sportima” ega dieet ei aita. Muutuma peab kogu komplekt – töö, vaba aeg, toitumine. Lihtne öelda, raske teha. Ja ega omakorda seda muudatust ei olegi võimalik ühekorraga või siis ühest otsast alustades teha. See muudatus on pikaajaline ja seda peab vedama mitmest otsast.

Esiteks: prioriteedid paika.

Enamasti on kõigil olemas vabandus – just täna on tööl väga palju teha, ainult täna jätame vahele. Kiire läheb aga mööda. Ärge saage valesti aru, ma ei kutsu üles minnalaskmisele või töö tegemata jätmisele. Kuid igal asjal on oma aeg ja kõigega tuleb hakkama saada. Kui ei tähtaeg tulemas, siis tuleb lihtsalt kauem teha, aga vahepeal tuleb trennis ära käia. Kui töötad õhtul, hommikul vara või öösel, siis ei ole enam kellelgi vahet, kas su töö valmib kell 22.00 või 23.00, peaasi et hommikuks valmis on. 

Alustada võib väga rahulikult – ma sättisin paika kaks trenni nädalas, mida ma kunagi ära ei jätnud. Mõttekas on valida need rühmatreeningud, mis algavad kindlal ajal ja seega ei saa viilida – “lähen 30, 45, 1 tund hiljem”.

Teiseks: las kõht räägib

Edasi hakkas mind huvitama, kas mu söömisharjumustes on süüdi kõht või aju. Ehk, äkki suudan ma põhimõtteliselt piiri pidada ja küsimus on vaid selles, et paljud söömised on asendus- või kõrvaltegevus.

Ostsin täpse köögikaalu, millel on taarafunktsioon ja otsustasin võrrelda sisse söödud toidu kogust ja kaloraaži sellega, mida mu kõht selle kohta ütleb. St. kas tegelikult tekib tunne “nüüd aitab” õigel ajal.

Nädala jooksul kaalusin ära kõik, mis üldse suhu läks, absoluutselt ilma ühegi erandita. Ka vähima toidutüki, isegi kohvi sisse pandava tilga piima. Samal ajal jälgisin, mida mu kõht räägib. Selgus oodatud, ometi tol hetkel hämmastav tõsiasi – kõht ütles väga täpselt, millal aitab ja vajalik kalorinorm käes on. See tähendas, et kui ma söön “kõhutunde” järgi, siis ei tohiks ülekaalust juttugi olla.

Teise positiivse efektina sain teada, kui palju tegelikult mingi esmapilgul tühine asi võib energiat sisaldada. Hommikune võileib üks viil näiteks 150-200kcal. Tass kohvi suhkruga sinna juurde 60kcal! Kuid norm üldse on kaalu langetamisel ju 300-400kcal negatiivset bilanssi päeva kohta. Ehk kahe võileivaga võib terve dieedi juba tühistada!

Kolmandaks: EI “täna söön, homme treenin” põhimõttele

Nii mugav – täna söön veidi rohkem, homme teen rohkem trenni. Muidugi, nii rangelt asja võtta ei saa. Nii nagu ei ole võimalik väga täpselt jagada kaloraaži (kaalujälgijad!), ei ole ka päevad sarnased. Samuti tuleb ikka ette sünnipäevi, grilliõhtuid ja muidu üritusi. Seal ei pea nurgas istuma ja oma kapsalehte närima. Kuid ei hakanud pealkirja keerukat “valemit” välja mõtlema. Pealkirja mõte on see, et ka grillipeol süües kontrollin end ja arvutan suures järgus kalorid kokku ja siis ka järgmisel päeval tõesti püüan need omakorda maha ajada. Ehk, variatiivsus nii koormuses kui toitumises on tegelikult looduse poolt ette nähtud ja normaalne. Seda täielikult vältida ei õnnestu ja ei olegi vajalik. Kuid nädala kaloraaž peaks juba rangelt negatiivne olema.

Neljandaks: kasuta ära saadud energia

Ümberkorraldused ja esimesed positiivsed märgid andsid jõudu ja energiat edasi tegutseda. Märkasin, et tegelikult kompenseerub trennis veedetud aeg suurema energiaga töö tegemiseks. Midagi tegemata ei jäänud, vastupidi, aega hakkas juskui juurde tekkima. Paljud vedelemised ja laisklemised kadusid ära. Võib öelda, et 1 tund trenni = +1 tund muude tegevuste jaoks leitud aega. Või teiste sõnadega, üks tund trenni aktiviseeris vähemalt ühe tunni päevast lisaks, mis muidu möödus passiivselt.

Ja nii see siis hakkaski minema. Edasi lisasin juba vabatahtlikult treeninguid juurde. Rühmatreeningule (BodyPump) lisasin tagasi jõusaali 1x nädalas. Seejärel lisasin aeroobse treeningu – ratas, sõudeergomeeter vms. Seejärel täitsin ära juba kõik päevad, tulemuseks 7x trenni nädalas – 2 BP, 2-3x jõusaal, 2x aeroobne.

Tulemused olid juba hämmastavad esimese poole aastaga – seejuures tegin sel perioodil trenni vaid 3x nädalas. Kusjuures kaalu langus esimese kuue kuuga ei olnudki midagi erilist – 6kg. Kuid Vomaxis mõõdetud muud näidud olid kõvasti muutunud:

Vererõhk: 80/140

Veel parem, koormuse all 70/190

Max hapnikutarbimine: 37 mg/kg.

Taastumine: 3 min

See tõestas, et suund on õige.

Kokkuvõte: kaal = kalorid sisse – liikumine

Kokkuvõtteks võib öelda, et väga triviaalne põhimõte – kaal sõltub sissesöödud ja kulutatud kalorite vahest – töötab sama raudselt nagu gravitatsioon ja päikesetõus hommikul. Kõikvõimalikud imedieedid on suur jama, ühed on teisest paremad vaid selle poolest kuivõrd katavad organismi toitainete vajaduse – ühekülgselt või mitmekülgselt. Tulemus aga sõltub sisse söödud ja kulutatud energiast. Mitte mingid imed ei ole võimalikud. Tuleb teha tööd ja mitte õgida.

Küll aga on selle valemi “kogemine” väga huvitav kogemus.

  • Alustasin 2-3x nädalas, trennis kulutatud kaloreid 2400 nädalas (kuna Vomaxis mõõdeti hapnikutarbimine täpselt, samuti pulss, siis pulsikell näitas täpselt). Vähendasin toitu peale trenni, st. trennijärgsetel õhtutel. Kaal langes 6kg 6 kuuga. Siis jäi aga püsima.
  • Otsustasin midagi ette võtta. Selge see, et nüüd ammugi mingeid “lollusi” tegema ei hakanud. Valem oli selge: rohkem trenni, vähem kaloreid. Hakkasin treenima 5x nädalas, lisasin intensiivsed kaloripõletamised. Osa toidust asendasin täielikult Biolabi pulbritega. Järk-järgult. Kõik hakkas liikuma jälle, jõudsin 102 kiloni. Edasi tekkis aga jälle seisak. Aeg: 1 aasta ja paar kuud möödas.
  • Nüüdseks oli aga kõht harjunud ütlema, millal aitab toidust. Kuid ainult koguseliselt. Samuti oli aga keha harjunud puhtamate toitudega. Igasugused ekstravagantsused ja niisama maiustamised gurmeega olid kadunud ja ega neist kahju ei olnud. Nüüd oli käes aeg kolmandaks muudatuseks. 7x nädalas trenn ja toit pudrud, salatid ja valgupulber (peamiselt jõusaali tarbeks). Järgnes vabalangus 93 kiloni, mis kestab edasi. Rasvaprotsent on 16% (nahavoldi mõõtmise järgi).

Ja lõpetuseks ka teistest näitajatest.

  • Jõusaalis on lisandunud raskusi tunduvalt. Samas olen üle läinud loomulikumatele baasharjutustele – lõuatõmbed, kükid kangiga, vaba kangiga harjutused jms. masinate asemel.
  • Sõudeergomeetril 500m keskmine aeg 45 minuti jooksul 2:57. 500m aeg 1:28.
  • Max hapnikutarbimine 48, pulss istudes 55.
  • Enesetunne hea, energiat palju, pulbri ja putrudega rahul :)

Ristiretk MS Entity Framework pühale maale

juuni 26, 2008 kirjutas neemevool

Nüüdseks umbes kaks aastat tagasi kirjutasin ühe programmi, millega saab genereerida SQL 2005 andmebaasi struktuurist C# klasse ehk vaese mehe ORM. Hiljem lisandusid võimalused genereerida neid olemeid manipuleerivad meetodid a la SaveEntity, DeleteEntity, FillEntityList jms. Samuti tekkisid SQL Compactiga sünkroniseerimist võimaldavad veebiteenused.

Ma ei pidanud seda rakendust kunagi täiemahuliste kommerts-ORMide konkurendiks, selle eeliseks oli aga täielik kontroll koodi üle mida see genereeris. Samuti genereeris see koodi, mis vastas täpselt just WinForms rakenduste vajadustele, mida paljud kommerts-ORMidki kahe silma vahele olid jätnud, näiteks OnChanged sündmused andmesidumise võimaldamiseks. Sestap ei pühendanud selle arendamisele enam aega kui hädavajalik.

Juba Teched 2007-l Hispaanias 2007 aasta novembris jagas MS laiali ajakirju, kus tutvustati kohe-kohe saabuvat MS Entity Frameworki, mis promo järgi pidi olema võimsaim ORM ever. See oli teine põhjus, miks ma ei arendanud enda töövahendit eriti tugevalt edasi.

See oli sissejuhatus, edasi tuleb aga ristiretke kirjeldus, mis lõpeb sellega, et maandusin esialgu jällegi “vana hea” ise genereeritud ORMi otsa ja uus ristiretk on kavas aastal 2009.

Esimene: kodust minema!

Projekteerides anno 2008 uut suuremat rakendust, tekkis küsimus, kas saaks ehk optimeerida klassikalise veebiteenustel töötava WinForms rakenduse arendustsüklit andmebaas->C# olemid->tüpiseeritud ASP.NET veebiteenus->SCSF andmeteenus->C# klient-olemid. Kuigi mul oli käepärast seesama enda arendatud ORM tööriist, suunasin otsingud kahele peamisele suunale.

Teine: SQL 2005 HTTP Endpoints ehk SQL 2005 veebiteenused

SQL 2005 server sisaldab võimalust näidata protseduure, funktsioone ja päringuid otse täiemahuliseks SOAP veebiteenuseks, kus ka WSDL kaasas. Seega kujuneks veebiteenuse kasutamine äärmiselt lihtsaks – kirjutada protseduur -> avada HTTP endpoint -> genereerida rakenduses wsdlist proxy klassid. Esiteks, elimineeritud oleks vajadus üleüldse mingit veebiteenuse koodi kirjutada (HTTP endpoint avamine on lihtne ja selle tekitamise saab lisada näiteks andmebaasi paigaldamise koodi, kuna on tavaline T-SQL).

Kolmas: WSDL tupiktee – olemite ühesuunaline liiklus

Loomulikult aga soovisin ma veebiteenust panna välja näitama mitte primitiivtüüpe vaid objekte, mida saaks tarbida otse või läbi vahekonverteri (mida saaks vähemalt automaatselt genereerida) normaalses OOP rakenduses. HTTP endpointe kasutades on see isegi teoreetiliselt võimalik: 1) deklaratsioonis saab ette anda ise genereeritud WSDLi, mis võib olla milline iganes. 2) veebiteenus ise ehk protseduur, mida see eksponeerib võib tagastada näiteks SQL serveri XML andmetüübi. Siit oleks vaid üks lühike samm rakenduseni. Siiski nõuab kokkuvõttes eriti just “tavapärase” tüpiseeritud veebiteenusega analoogse WSDLi moodustamine tuntavat pingutust, sest kuigi “for XML” päringud saab panna väljastama ka mitte tulemust, vaid XML schemat, on saadud XML schema vaid päringu tulemuse kirjeldus primitiividena, mitte aga mingi olemina. Ok, teostatav. Kuid veel suurem takistus ilmneb olemite tagastamisel ehk näiteks SaveEntity(Entity x) loomisel. Kui väljastamisel oli teoreetiliselt võimalik veel vajalik WSDL saavutada (vihje: XML andmetüüp sproc väljundina – ärge küsige minult näitekoodi, viskasin lõpuks kõik minema ja katsefaile otsida ei viitsi), siis nn. tagasisalvestamisel oleks vastupidine trikk kindlalt hambad murdnud (siiski võimalik – XML andmetüüp -> SQL 2005 XML XQUERY sproc muutujateks -> sproc salvestamine.) Kokku aga siiski juba nii palju lisatööd, et muudab mängu mõttetuks. Ehk, kogu HTTP endpointide ilu  rikkus ära just salvestusoperatsioonide keerukus.

Ja lõpuks leidsin MS blogidest vihje, et SQL 2008-s on HTTP Endpointid nagunii “deprecated” ja asendatakse peagi ADO.NET Data Services tehnoloogiaga, mis töötab ADO.NET Entity Framework peal ja on veelgi vingem. Otsustasin, et uue projekti jaoks ei ole ilmselt mõistlik kasutada tehnoloogiat, mis on järgmises versioonis “vananenud”. Muidugi, kuni lõpeb 2005 tugi kuluks veel aastaid ja ilmselt sureks ka uus rakendus enne kui SQL 2005, tekitab probleeme hoopis paanika, mis arendajate seas tekib kohe kui MS teatab millegi “deprekeerimisest” – HTTP endpointide kohta leiab niigi vähe infot, ja ilmselt seda juurde ka ei tule kuna tehnoloogia on kuulutatud kaduvaks.

Kokkuvõte – SQL 2005 endpoints on hea vahend näidata välja ad hoc andmeid ilma massiivse veebiteenuse koodi kirjutamiseta. Näiteks tarbimiseks Excelis vms. kus peamiselt liiguvad andmed ühes suunas. Kuid klassikalise OOP CRUD süsteemi jaoks on kõlbmatu.

Neljas: ADO.NET Data Services tõotatud maa

ADO.NET Data Services on just jõudnud koodnimest Astoria viimase beetani, ametlik ADO.NET Data Services ja Entity Framework peaks valmis saama selleks sügiseks ehk täpselt õigeks ajaks. Hetkel (juuni 2008) väljas olevas .NET 3.5 SP1 beetas ilmselt ei muutu enam dramaatiliselt midagi peale bugfixide (nagu MS projekti tiim kirjutab, vt. Astoria Team Blog). Seega väga sobiv kandidaat – uus, värske, peagi valmis ja ilmselt niipea ei “vanane”.

Esimeste olemite genereerimine baasist, nende eksponeerimine veebiteenustes kulges suuremate tõrgeteta ja tuleb tunnistada, et võrreldes SQL 2005 HTTP endpointidega on OOP CRUD väga lihtne. Hoolimata sellest, et süsteem tuleb esialgu paigutada ASP.NET veebiteenusesse, käib kogu vajaliku koodi genereerimine automaatselt ja seega võib selle pidada hallatavuselt ekvivalentseks HTTP endpointidega hoolimata rakenduse asumisest kahel platvormil.

Esimene tõrge tekkis aga protseduuride välja näitamisel. Nimelt peale esimest kahte triviaalset tabelit oli vaja kolmanda sammuna näidata andmeid, mille arvutamine sprocina oli ainumõeldav. Tegu oli teatava ajagraafiku arvutamisega, kus lähteandmeteks on loetelu sündmuste toimumisest – kas üksikute kuupäevadena või siis korduvusreeglitena, millest tuli lahutada nn. erandkuupäevad. Kasutajale ja ka andmebaasile on kõige sõbralikum sellist infot hoida kahes tabelis – graafik ise (sh. korduvused kujul intervalli algus, intervalli lõpp, korduvusreegel) ja erandid (mis lülitasid korduvusreeglist teatud kuupäevad välja – näiteks “igal nädalal teisipäeviti, välja arvatud 23. juuni”). Nende pealt aga tuleb graafikus kuvamiseks komponeerida lõplik graafik. Muidugi, seda saaks teha ka veebiteenuses otse ja C# koodis oleks see triviaalne. Kuid probleemiks oli see, et graafikut vajavad ka moodulid, mis ei tarvita veebiteenust. Seega oleks äriloogika paiknenud mitmes kohas.

Seega oli vaja kuvada ADO.NET Data Services abil välja sproci andmed. Ma arvasin, et see on triviaalne, sest a) esialgne Astoria manuaal kirjeldas seda b) minu jaoks oli ilmne, et maailmas, kus suur osa andmete ligipääsu on teostatud sprocidena (seda on ju jutlustatud aastaid), ei saa ADO.NET Data Services ilma selleta läbi.

Tõde oli aga kohutav – ADO.NET Entity Framework v.1.0 ei toeta nn. read sproce ehk sproc->ADO.NET Entity->teenus. Sprocidel on koht vaid CUD (Create, Update, Delete) maatriksis, kus on võimalik andmete manipuleerimisse sekkuda.

Erinevalt HTTP Endpointide tupikust, kust (kuna lubati uut võimsamat Entity Frameworki) kiiresti tagasi pöördusin, tegin siin mitmeid kiireid otsinguid probleemi lahendamiseks.

1. suvaline sproc on võimalik kenasti importida EF (Entity Framework) Function Impordiks ja seda saab otse [WebGet] või [WebInvoke] meetodis kasutada nii, et ei ole vaja minna veel Data Services tehnoloogiat mõttetuks muutva SQL kirjutamiseni. Kuid, IEnumerable [WebGet]  meetodi kutsub EF kliendi osa välja kujul WebGetMethodName()?args isegi juhul, kui anda sellele parameetrid. Jah, eemaldades () sulud väljakutses (näiteks kirjutades päringu otse brauserisse või siis käsitsi koostades päringu urli, mitte dataContext.AddParameter) kõik töötab – kuid vaid seni, kuni MS otsustab selle “augu” likvideerida RTMis. Seega oleks oma koodi sellele häkile üles ehitada ohtlik.

2. WebGeti kirjutamine IQueryablet tagastavaks nõuab klassi koostamist, mis implementeerib IQueryable. Sproci wrapper seda ei ole. Lisaks ilmusid blogidesse ja foorumitesse teated, et “returning primitive types as IQueryable<type> is not supported” – anymore. Seega ei maksaks ehitada üleüldse oma lootusi seda RTMis näha, isegi kui ehitaks valmis IQueryable objekti sproc tulemuse peale (mida ma ka isegi tegin).

3. Well, edasi on võimalus luua “legaalne” EF olem, mida IQueryable Webget probleemideta väljastab ja ADO.NET Data Services klient ka korrektselt tarbib. Kuid, ärge lootkegi et saate EF olemi väljastada sproci tulemusena. Ehk, lugege edasist nagu anekdooti, kus puänt on viimasel real:

a) Olemi (Entity) loomine on täiesti ok ja loomulikult legaalne tegevus

b) sprocist, mis tagastab täpselt olemile vastava signatuuriga andmed, saab legaalsete vahenditega luua Function Impordi. Disaineris saab sproc tagastatavaks andmetüübiks valida loodud olemi (sic!). Kuid sellega ei ole halligi edasi teha. Loe edasi …

c) VS keeldub rakendust kompileerimast, sest “entity is not mapped”. Nimelt, iga olem peab olema mäpitud _tabelile_ (WTF see sproci andmetüübi määramine siis üldse on??).

d) Nüüd algab nali. MS EF tiimi liikmed annavad foorumites soovitusi, mida kadestaks isegi Dogbert Dilberti koomiksites. Jah, .edmx xml failidesse saab tekitada “virtuaalsed” tabelid käsitsi XMLi tehes, millest omakorda saab mäppida väljad sproci väljundisse – ja kõik töötab. Usinamad tiimiliikmed on teinud lausa tutorialid, mõned lausa edmx faili “tweakimise” utiliidid. Kuid puänt on selles, et kogu “lisatud” kood lendab vastu taevast kohe, kui te soovite lisada või uuendada mõnda “legaalset” tabelit andmebaasist. MS koodi genereerimise utiliit mitte ei uuenda vastavaid lõike koodis vaid genereerib kogu koodi uuesti. Ja kogu töö on vastu taevast. Tunnen kaasa neile õnnetutele foorumi külastajatele, kes kurdavad isegi kuni kahest kuust raisatud ajast, kuni jõuti sproci teemani.

Ma ei suuda uskuda, kuidas on võimalik et MS ignoreeris algusest peale seda ilmset fakti, et de facto on suur osa andmeloogikat ehitatud sprocidesse ja mitte ainult CUD loogika.

ADO.NET Data Services Program Manager aga tunnistab lõpuks tehtud jama ja ütleb, et “read” sprocide tugi tuleb Entity Framework v. 2-te. Ja millal tuleb Entity Framework v. 2? “somewhere in 2009″. Seniks aga kasutage MS poolt kiiresti kokku häkitud “EF Extensione” ehk C# koodi millega saab EF-ist ikkagi sprocide andmeid kätte. Edu neile, kes julgevad kasutada selliseid häkke, mille MS võib iga hetk aknast välja visata.

Viies: tagasi koju, püha Graal jäi leidmata

Kokkuvõte – ADO.NET Data Services ja Entity Framework on kahtlemata suurepärane ORM ja triviaalse CRUD koodi kirjutamine võrreldes HTTP endpointidega või mõne muu ORMiga on mugav ja kiire. Kuid selles haigutab meeletu auk kohas, kus andmed ei paikne lihttabelites. Samuti teeb ettevaatlikuks kogu projekti kestel mitu korda muutunud reeglid veebiteenuste tarbmisel. Seega lükkan EF kasutamise edasi aastasse 2009 EF 2.0-ni (kui selleks ajaks see projekt veel elab) ja kasutan end tõestanud kommerts-ORMe või siis oma vana head kodukootud rakendust.

Epiloog: kodumaja on alles

Siiski, kuna lõin EF-t tarvitava rakenduse SCSF ja OOP klassikalisi reegleid järgides, kulus EF->enda ORM modifikatsiooniks vaid paar loetud tundi. Kuna rakendus oli arhitektuurselt jaotatud MVP mustriks, kus teenus kasutas ADO.NET Data Services teenuseid läbi EF Data Contect peale loodud wrapperite, pidin muutma vaid reaalselt EF-i päringuid tegeva koodi SOAP WS päringuid saatvaks koodiks. Kõik muu töötas edasi. Fantastiline.

ClickOnce rakenduse publitseerimine TFS 2008 Team Build abil

Mai 13, 2008 kirjutas neemevool

Selle teksti mõte on dokumenteerida enda tarbeks ClickOnce abil publitseeritava rakenduse komplekteerimine TFS build abil, kuna MSDN abitekstid (http://msdn.microsoft.com/en-us/library/xc3tc5xx.aspx) osutusid jällegi puudulikeks, vigasteks ja eksitavateks (jätsin sinna ka kommentaari).

Teiseks, eriti just SCSF rakenduse publitseerimisel ei saa kasutada out-of-the-box TFS Team Buildi, sest see nõuab projekti ülesehitust, kus kogu SCSF mõte kaob. SCSF tugevus seisneb aga selles, et rakendus on võimalik kokku panna erinevate arendajate poolt loodud moodulitest, mis ei pruugi olla ühes versioonikontrolli harus ega isegi mitte samas serveris. Või siis tarnivad mõned arendajad oma mooduli .dllina. Seega on vaja süsteemi, kus Team Build abil on võimalik kogu Smart Client rakendus kokku panna nö. algosadest.

ClickOnce rakenduse publitseerimisel võib olla vähemalt kaks lähtepunkti:

  1. rakendus on kompileeritud (dll-id, konfiguratsioonifailid jms.) ja see on vaja vaid komplekteerida (näiteks SmartClient) lisades/eemaldades komponente.
  2. rakendus on lähtekoodi kujul, vaja on kompileerida ja publitseerida.

Alljärgnev sobib mõlemale juhule, punkt 1. on punkti 2. alamosa.

1. Ettevalmistused

ClickOnce rakendus on kohustuslik signeerida. Selleks on vaja signeerimissertifikaati. Testrakenduse signeerimiseks sobib ka ise genereeritud sertifikaat. Windows SDK-s on selleks tööriist makecert

1. Loo sertifikaat: makecert -sv mykey.pvk -n “CN=myname” mykey.cer genereerib nii privaatvõtme kui ka sertifikaadi. CN=myname on muidugi vaid osa sertifikaadi tunnusest, reaalse sertifikaadi genereerimiseks on vaja rohkem infot.

2. Loo signeerimiseks vajalik võtmefail utiliidiga pvk2pfx: pvk2pfx -pvk mykey.pvk -spc mykey.cer -pfx mykey.pfx -po pfxparool, kus pfx parool on eraldi parool allkirjastamisel pfx võtme avamiseks ja ei tohiks olla sama mis privaatvõtme ja sertifikaadi genereerimisel.

3. Kontrolli, kas masinas (seega siis Team Build masin), kus töötad, on Publisher info olemas. Nimelt on ClickOnce publikatsiooni puhul vajalik Publisher info. Selle võid enne signeerimist kirjutada publikatsiooni manifesti teegina

<description asmv2:publisher=”<fimanimi>” asmv2:product=”<tootenimi>” asmv2:supportUrl=”<tugilehe URL>” xmlns=”urn:schemas-microsoft-com:asm.v1″ />

või siis märkida registrisse võtme
HKEY_LOCAL_MACHINE\SOFTWARE\MIcrosoft\Windows\
WIndowsNT\CurrentVersion\RegisteredOrganization alla.

2. Koodi ja teekide alla laadimine

Et me saaks koodi jms. laadida alla suvalistest versioonikontrolli harudest, peame ise tekitama workspace ja selle mappingud. Defineerime kogu keskkonna põhimuutujad – kuhu lähevad kompileeritud asjad, kuhu tõmmatakse lähtekoodid ja mis on loodava workspace nimi:

<PropertyGroup>
    <
OutputPath>C:\TFSBuilds\projekt\bin\</OutputPath>
    <
RootPath>C:\TFSBuilds\projekt\</RootPath>
    <
WorkspaceName>projektDEV</WorkspaceName>
    <
Tf>tf</Tf>
</
PropertyGroup>

Edasi defineerime versioonikontrolli mappingud töökeskkonda:

<ItemGroup>
<
WorkspaceMapping Include=$/DEV/kood>
    <
LocalPath>$(RootPath)kood</LocalPath>
</
WorkspaceMapping>
</ItemGroup>

Muidugi võib neid mappinguid olla rohkem.

Seejärel tekitame töökeskkonna targetiga CreateWorkspace:

<Target Name=CreateWorkspace>
    <!–
Checking input parameters –>
    <
Error Condition=$(WorkspaceName) == ”           Text=Please specify WorkspaceName property/>
    <
Error Condition=$(RootPath) == ”           Text=Please specify RootPath property/>
    <
Error Condition=!HasTrailingSlash(‘$(RootPath)’)           Text=Please make sure RootPath is slash terminated/>
    <
Exec Command=$(Tf) workspace /delete &quot;$(WorkspaceName)&quot; ContinueOnError=true IgnoreExitCode=true/>
    <!–
Create new workspace–>
    <
Exec Command=$(Tf) workspace /new /noprompt &quot;$(WorkspaceName)&quot; />
    <!–
Remove default mapping –>
    <
Exec Command=$(Tf) workfold /unmap /workspace:&quot;$(WorkspaceName)&quot; $//>
    <!–
Create new mappings (uses MSBuild batching) –>
    <
Exec Command=$(Tf) workfold /map &quot;%(WorkspaceMapping.Identity)&quot; &quot;%(WorkspaceMapping.LocalPath)&quot; /workspace:&quot;$(WorkspaceName)&quot;/>
    <!–
Great success! –>
    <
Message Text=Workspace ‘$(WorkspaceName)’ created sucessfully/>
    <!–
List created mappings –>
    <
Exec Command=$(Tf) workfold /workspace:&quot;$(WorkspaceName)&quot;/>
</
Target>

Laeme alla koodi loodud workspace:

<Target Name=GetProjects DependsOnTargets=CreateWorkspace>

<!– Get the sources for the given workspace–>
<
Get TeamFoundationServerUrl=$(TeamFoundationServerUrl)
     BuildUri=$(BuildUri)
     Workspace=$(WorkspaceName)
     Version=T
     Filespec=$/DEV/kood
     PopulateOutput=$(GetPopulateOutput)
     Overwrite=$(GetOverwrite)
     Preview=$(PreviewGet)
     Recursive=$(RecursiveGet)
     Force=$(ForceGet)>
    <
Output TaskParameter=Gets ItemName=Gets />
    <
Output TaskParameter=Replaces ItemName=Replaces />
    <
Output TaskParameter=Deletes ItemName=Deletes />
    <
Output TaskParameter=Warnings ItemName=GetWarnings />
</
Get>

</Target>

Kus siis Filespec tähistab mingit elementi (haru, fail vms.) versioonikontrollist. Get lõiku kordame nii palju kui vaja, soovi korral võime laadida ka mitte viimase, vaid mingi muu versiooni jne.

Edasi puhastame kompileerimiskoha:

<Target Name=ClearBin>
    <
RemoveDir Directories=$(OutputPath)/>
    <
MakeDir Directories=$(OutputPath)/>
   
</
Target>

Seejärel kompileerime projektid, mille tõmbasime alla lähtekoodina:

<Target Name=CustomBuild DependsOnTargets=CopyLibraries>
   
    <
MSBuild Projects=$(RootPath)kood\kood.csproj
             Properties=OutputPath=$(OutputPath);NoWin32Manifest=true;/>
</Target>

VS2008 ja ClickOnce puhul on eriti oluline kompileerimislipp NoWin32Manifest=true, et kompileerimisel ei lisataks manifesti kompilatsioonidesse. Pärast rakenduse manifesti genereerimisel satub see vastuollu ClickOnce manifestiga ja tulemuseks on müstiline (MS poolt lahti seletamata) veateade “Reference in the manifest does not match the identity of the downloaded assembly”.

Edasi defineerime ClickOnce rakenduse versiooni ja publitseerimise muutujad, kus ShellExe on SCSF rakenduse koorik, DeploymentDir on koht, kuhu publitseeritakse rakendus (NB! versiooni alamkataloog luuakse hiljem), DeployUrl on aga koht, kust rakendus kasutajale paistma hakkab (jälle ilma versiooniharuta):

<PropertyGroup>
    <
Major>1</Major>
    <
Minor>0</Minor>
    <
Build>0</Build>
    <
Revision>0</Revision>
</
PropertyGroup>
<PropertyGroup>
    <
ShellExe>Shell.exe</ShellExe>
    <
DeploymentDir>C:\software\dev\</DeploymentDir>
    <
DeployUrl>http://software.dev.ee/dev/</DeployUrl>
    <
SupportUrl>http://www.dev.ee/</SupportUrl>
</
PropertyGroup>

Edasi defineerime rakenduse koosluse koorikust (exe), teekidest (dll) ja failidest (nii tavalised kui andmefailid):

<ItemGroup>
<
EntryPoint Include=$(OutputPath)$(ShellExe)/>

<Dependency Include=$(OutputPath)Microsoft.Practices.CompositeUI.dll>
    <
AssemblyType>Managed</AssemblyType>
    <
DependencyType>Install</DependencyType>
</
Dependency>

<File Include=$(OutputPath)ProfileCatalog.xml>
    <
TargetPath>ProfileCatalog.xml</TargetPath>
</
File>

<File Include=$(OutputPath)Data\Data.sdf>
    <
TargetPath>Data\Data.sdf</TargetPath>
    <
IsDataFile>true</IsDataFile>
</
File>

</ItemGroup>

Nüüd saame publitseerida rakenduse alamversiooniga kataloogi:

<Target Name=ClickOnceDeploy DependsOnTargets=CustomBuild>
    <
Version VersionFile=$(RootPath)versionnumber.txt BuildType=None RevisionType=Increment>
        <
Output TaskParameter=Major PropertyName=Major />
        <
Output TaskParameter=Minor PropertyName=Minor />
        <
Output TaskParameter=Build PropertyName=Build />
        <
Output TaskParameter=Revision PropertyName=Revision />
    </
Version>
    <
GenerateApplicationManifest
        AssemblyVersion=$(Major).$(Minor).$(Build).$(Revision)
        Dependencies=@(Dependency)
        Description=Shell
        Files=@(File)
        EntryPoint=$(OutputPath)$(ShellExe)
        OutputManifest=$(OutputPath)$(ShellExe).manifest>
        <
Output
            ItemName=ApplicationManifest
            TaskParameter=OutputManifest
            />
    </
GenerateApplicationManifest>
<!– signeerime rakenduse manifesti –>
    <
Exec Command=mage -s $(OutputPath)$(ShellExe).manifest -cf $(RootPath)mykey.pfx -pwd pfxparool/>
<!– genereerime publikatsiooni manifesti –>
    <
GenerateDeploymentManifest
        EntryPoint=@(ApplicationManifest)
        AssemblyName=$(ShellExe).application
        AssemblyVersion=$(Major).$(Minor).$(Build).$(Revision)
        DeploymentUrl=$(DeployUrl)$(Major)_$(Minor)_$(Build)_$(Revision)/$(ShellExe).application
        MapFileExtensions=true
        Install=false
        OutputManifest=$(OutputPath)$(ShellExe).application
        Product=Albert Editor
        Publisher=AS Firma
        SupportUrl=http://www.firma.ee/
        UpdateEnabled=false>
       
        <
Output
            ItemName=DeployManifest
            TaskParameter=OutputManifest
            />
    </
GenerateDeploymentManifest>
<!– signeerime publikatsiooni manifesti –>
    <
Exec Command=mage -s $(OutputPath)$(ShellExe).application -cf $(RootPath)mykey.pfx -pwd pfxparool/>
<!– loendame rakenduse failid –>
    <
CreateItem
       
Include=$(OutputPath)**\*.*
        Exclude=$(OutputPath)**\*.manifest;$(OutputPath)**\*.application
                >
        <
Output ItemName=DeploymentFiles TaskParameter=Include/>
    </
CreateItem>
<!– kopeerime failid, andes laiendi .deploy –>
    <
Copy
       
SourceFiles=@(DeploymentFiles)
        DestinationFiles=@(DeploymentFiles->’$(DeploymentDir)$(Major)_$(Minor)_$(Build)_$(Revision)\%(RecursiveDir)%(Filename)%(Extension).deploy’)/>
    <
Copy SourceFiles=$(OutputPath)$(ShellExe).manifest DestinationFolder=$(DeploymentDir)$(Major)_$(Minor)_$(Build)_$(Revision)/>
    <
Copy SourceFiles=$(OutputPath)$(ShellExe).application DestinationFolder=$(DeploymentDir)$(Major)_$(Minor)_$(Build)_$(Revision)/>
</Target>

ID kaardi põhise autentimise seadistamine IIS 6.0-s

Mai 7, 2008 kirjutas neemevool

Kirjutamise põhjuseks on www.id.ee peal olev eksitav juhend: http://www.id.ee/10456?id=10737 . Selle juhendi üle on kaevanud ka teised: http://dukelupus.wordpress.com/2006/12/24/tants-id-kaardi-umber-ehk-iisi-ja-id-kaardi-suhtlema-panemine/

Kuna samuti kulutasin selle “üllitise” järgi IIS 6.0 konfigureerides mitu tundi oma aega, siis kirjutan teise versiooni sellest.

Siiski, ma ei ole testinud seda lahendust kõikidel Windows serveri platvormidel, tegin selle läbi Windows Server 2003 R2, Standard Edition, Service Pack 2 peal.

1. Installeeri IISi SSL tugi. SSL on vajalik, IIS ei aktiveeri kliendilt sertifikaatide küsimist üle HTTP.

Selleks:

a) osta, generereeri või hangi testsertifikaat. SSL sertifikaatide pakkujaid on väga palju ja hinnad on väga erinevad. Erinevused tulevad peamiselt sellest, kas SSL sertifikaadi pakkuja on kõigis enamlevinud brauserites registreeritud või mitte. Lisaks muud “äriteenused” ja “võimalused”, nagu näiteks “wildcard SSL” jms. Ise ostsin SSL sertifikaadi Thawtelt, sealtsamast saab ka 21 päeva kehtiva ajutise sertifikaadi. Thawte ostu protsess on samuti kõige arusaadavam.

b) kuidas täpselt SSL sertifikaati IISi paigaldada, võib lugeda kahte allikat kombineerides: Thawte lehelt dokumendist https://www.thawte.com/ucgi/gothawte.cgi?a=w44600158747054000 (Securing your Microsoft Internet Information Services (MS IIS) Web Server with a thawte Digital Certificate ja raamatust Microsoft IIS 6.0: Administrator’s Pocket Consultant, William R. Stanek, ISBN: 0735615608. Viimati nimetatud raamatus peatükk 8 on väga lakooniline ja samas täpne.

2. Kontrolli, et IIS suudab üle HTTPSi serveerida.

3. Lae Sertifitseerimiskeskuse lehelt alla sertifikaadid: http://www.sk.ee/pages.php/0202040501 

Sul on vaja PEM formaadis sertifikaate: Juur-SK, ESTEID-SK ja ESTEID-SK 2007.

Kindlam viis on sertifikaadid installeerida Windows Serveri halduskonsoolis, selleks:

a) Start->Run, kirjuta mmc, OK. Avaneb tühi konsool.

b) konsoolis vali File->Add/Remove Snap In, avanenud aknas vajuta nuppu Add…

c) avanenud uues aknas vali nimekirjast Certificates, vajuta Add. Avaneb uus aken, kus vali Compute account. Finish, Close.

d) vajuta järelejäänud aknas OK.

e) Halduskonsooli tekitati Certificates puu, kus ava Trusted Root Certification Authorities ja parema hiire klikiga vali selle peal All Tasks -> Import. Vali JUUR-SK.PEM.cer ja impordi.

f) Impordi sertifikaatide harusse Intermediate Certification Authorities/Certificates alla ESTEID-SK.PEM.cer ja ESTEID-SK 2007.PEM.cer

4. Ava IIS halduskonsool, vali veebisaidi, millele soovid ID autentimist rakendada omadused (Properties). Kaardilt Directory Security (mis peaks juba tuttav olema, kuna sealt paigaldasid ka eelnevalt SSL sertifikaadi) vajuta osas Secure Communications nuppu Edit …

a) võid märkida valikukasti Require secure channel – kuid ID kaardiga autentimiseks ei ole see kogu saidile vajalik.

b) vali Client certificates alt vähemalt Accept client certificates (arusaadavatel põhjustel ei ole mõtet valida Ignore …)

c) Tee linnuke valikukasti Enable certificate trust list. Kui sul veel ei ole ühtki, siis vali New. Avanenud viisardis vajuta nuppu Add From Store, kus avanenud aknas lisa JUUR-SK sertifikaat.

Juhul, kui kasutad test-SSL sertifikaati, siis pead valima lisaks ka juursertifikaadi SSL jaoks (mina näiteks Thawte Test CA Root).

Certificates in the CTL ehk Certificate Trust List loetleb JUURsertifikaadid, mille sertifikaate aktsepteeritakse.

5. Edasi võid ID kaardiga autentimiseks valida mitmeid tehnikaid – kuid, sa ei pea sugugi kõiki faile tingimata kaitsma ID kaardi autentimisega. Piisab, kui su lehel leidub üks fail, nt. login.aspx, mille puhul nõutakse autentimist ja login.aspx seab püsti juba sessiooni, näiteks cookie põhise. Edasi teised failid kasutaks siis juba enda loodud sessiooni. See on otstarbekas näiteks siis, kui lehel saab mitmel moel autentida.

6. Login.aspx ID autentimist küsima panemiseks vali IIS halduskonsoolis veebisaidi failide nimekirjast Login.aspx ja parema nupuga kuva omadused ehk Properties.

a) vali File Security kaart, sealt Secure Communications osast vajuta Edit …

b) Tee linnuke valikukasti Require secure channel (SSL)

c) Client Certificates osast vali vähemalt Accept client certificates. Sa ei pea valima Require client certificates, sest juhul, kui kasutaja keeldub ID kaardiga autentimast, peaksid saama endiselt pakkuda kasutajale alternatiive, mitte keelduma näitamast login lehekülge.

7. Nüüd jääb teha veel saidipõhine autentimis- ja sessioonilahendus. Väga lihtne näide, kuidas ilma sertifikaadi aegumist kontrollimata lugeda aspx failis isikukood ja nimi:

if (Request.ClientCertificate["Subject"].Length == 0)
        {
            Response.Write(“Ei antud sertifikaate”);
        }
        else
        {
            String unparsed=Request.ClientCertificate["Subject"];
            System.Text.RegularExpressions.Regex re = new Regex(“SERIALNUMBER=(\\d{11})”);
            Response.Write(“<br/>unparsed:” + unparsed + “<br/>”);
            if (re.IsMatch(unparsed))
            {
                String idcode = re.Match(unparsed).Groups[1].Value;
                Response.Write(“Su isikukood on:” + idcode + “<br/>”);
            }
            System.Text.RegularExpressions.Regex rename = new Regex(“SN=(.*?),\\s+G=(.*?),”);
            if (rename.IsMatch(unparsed))
            {
                String eesnimi = rename.Match(unparsed).Groups[1].Value;
                String perenimi = rename.Match(unparsed).Groups[2].Value;
                Response.Write(“Su nimi on: “+eesnimi+” ” +perenimi+”<br/>”);
            }
        }

WiX põhise MSI installeri crashcourse

aprill 21, 2008 kirjutas neemevool
  1. Ma ei kirjuta siin (veel) sellest, mis on WiX – vt. http://www.tramontana.co.hu/wix/index.php
  2. Ma ei kirjuta, kuidas saada WiX tööle VS 2008 all – hetkel enam ei mäleta, kui arvuti crashib, eks siis tuletan meelde ja kirjutan ka blogi.
  3. Kirjatüki mõte on dokumenteerida enda jaoks nn. WiX 1-2-3 töö alustamiseks, et iga kord ei peaks WiX mahukast materjalist läbi närima ja meelde tuletama – “kuidas see kõik nüüd käis”.

Lähteülesanne

  1. Peatada Windows teenus
  2. Paigaldada uued teenusefailid (teenuse exe jms.) – küsida kasutajalt enne nende asukohta
  3. Küsida kasutajalt SQL serveri (kus asuvad teenuse poolt kasutatavad SQL SP-d) andmed, kontrollida ligipääs.
  4. Vajadusel uuendada SQL SP-d.
  5. Käivitada teenus

1. Samm – WiX projekt

  1. kohanda Product teek, sisestades väärtused:
    1. Id – GUID saad nt. Tools->Create GUID
    2. Name – kirjuta toote nimi, mitte installika nimi
    3. Version – installitava rakenduse versioon
    4. UpdgradeCode – vt. tutorial.
  2. Kohanda Package teek, kindlasti sisesta Id. Package Id-d tuleb alati muuta, kui ükskõik milline osa paigaldusest (failid vms.) on muutunud.

2. Samm – loo kataloogide struktuur ja lisa failid

  1. Loo Directory teekidest hierarhia

3. Samm – defineeri komponendid

Kuidas failid, featuurid jms. komponentideks komplekteerida, sõltub rakendusest.

Igale komponendile tuleks anda viisakas ID ja genereerida Guid, mis peaks muutuma siis ja ainult siis, kui komponendis on mingeid muudatusi.

Iga komponent sisaldab/ei sisalda faile (File). Iga faili puhul tuleb näidata, kus see fail on kompileerimise hetkel ja mis on selle faili nimi installeerides.

Kuna soov on saavutada kompileeritavust ka TFS-is, siis peaks nii installeeritavad kui ka mitte installeeritavad (nt. SQL skriptid vms.) paigutama mingisse alamkataloogi või teise kohta, kindlasti mitte piirduma vaid Name atribuudiga, et WiX ei hakkaks faile ise taga otsima.

Testimiseks võib msi käivitada käsurealt:
msiexec /i msifail.msi /l*v install.log

ja mahavõtmiseks:

msiexec /x msifail.msi

Võti /l*v on eriti kasulik debugimise ajal, sest sel juhul logitakse tekstifaili detailsed veateated. Käsitsi msi-d käivitades aga teatab msi paljude vigade korral lakooniliselt “Error 2819″ ja lõpetab töö.

4. Tingimuste kontroll

Kõige triviaalsemad tingimused on näiteks failipõhised – kas mingi fail eksisteerib kuskil või mitte.

Selleks tuleb lisada Product teegi alla (nt. peale Directory teeki) plokk:

<Property Id=”CONFIGEXISTS”>
<DirectorySearch Id=”CheckConfFileDir”  Path=”[INSTALLLOCATION]” Depth=”0″>
<FileSearch Id=”CheckConfFile” Name=”filetocheck” />
</DirectorySearch>
</Property>

Edasi saab seda tingimust kontrollida, kui lisada Feature teeki tingimus:

<Condition Level=”0″>NOT CONFIGEXISTS</Condition>

Kus CONFIGEXISTS viitab Property=”CONFIGEXISTS” peale.

5. Installatsioonikoha muutmine kasutaja poolt

Selleks võib Feature teegile lisada Display ja ConfigurableDirectory parameetrid, määratud peavad olema ka Title ja Description. ConfigurableDirectory viitab Directory teekide hulgas Directory.Id peale, mida kasutajal lubatakse muuta.

6. UI määramine

Standarseid kasutajaliideseid on 4, UI määramiseks ühe nende seast tuleb Product teegi alla lisada:

<UIRef Id=”WixUI_Mondo” />
<UIRef Id=”WixUI_ErrorProgressText”/>

Samuti tuleb projekti viidetesse lisada WixUIExtension.dll.

NB! Kõi Feature-d ilmuvad valikute alla ainult siis, kui tingimus(ed) Feature juures on täidetud.

7. WixUI_Mondo juurde kuuluva litsentsiteksti muutmine ja ikoonide muutmine

License.rtf faili viitamiseks tuleb aga ka üle kirjutada muutuja WixUILicenseRtf, seda Product tasemel:

<WixVariable Id=”WixUILicenseRtf” Value=”Bitmap\License.rtf” />

Standardsete graafikafailide muutmiseks tuleb defineerida muutujad:

  1. WixUIBannerBmp – Top banner, 493 × 58
  2. WixUIDialogBmp – Background bitmap used on welcome and install-complete dialogs, 493 × 312
  3. WixUIExclamationIco – Exclamation icon on the wait-for-costing dialog, 32 × 32
  4. WixUIInfoIco – Information icon on the cancel and error dialogs,
    32 × 32
  5. WixUINewIco – Button glyph on directory-browse dialog, 16 × 16
  6. WixUIUpIco – Button glyph on directory-browse dialog, 16 × 16

8. Dialoogiakende loomine

Enda dialoogiakende loomiseks tuleb panna need .wxs failidesse. Kõige mugavam on dialooge redigeerida mitte käsitsi, vaid Wixedit abil.

Edasi tuleb dialoog “haakida” valitud põhidialoogi Next ja Back nuppude abil. Selleks tuleb valitud põhidialoogi .wxs failist teha projekti koopia. WiX UI failid on Wix lähtekoodi kataloogis src\ext\UIExtension\wixlib.

Kõige mugavam on oma dialooge haakida dialoogide vahele, kus ei ole palju võimalusi edasi-tagasi liikumiseks. St. halb on dialooge panna vahele sellistesse kohtadesse, kuhu kasutaja võib liikuda mitut teed pidi. Mondo puhul on sobiv koht LicenseAgreementDlg ja SetupTypeDlg vahel ehk kohe peale litsentsiga nõustumist kuid enne installatsioonitüübi valikut. Muidugi, kui tegemist on valikutega, mis sõltuvad eelnevalt valitud installeerimistüübist, siis tuleb rohkem vaeva näha ja lisada dialooge mujale ning kontrollida kasutaja valikud.

9. UI elementide aktiveerimine/inaktiveerimine sõltuvalt kasutaja valikutest

Mingi UI elemendi aktiveerimiseks/inaktiveerimiseks näiteks CheckBox oleku peale võib vastava Control teegi sisse kirjutada tingimused:

<Condition Action="disable"><![CDATA[SQLTEST <> "1"]]></Condition>
<Condition Action="enable">SQLTEST = "1"</Condition>

Antud näites juhib siis elementi CheckBox:

<Control  Property="SQLUSEWINDOWSAUTH"
      CheckBoxValue="1" Type="CheckBox"      Width="128" Height="17" X="210" Y="105"      Id="SqlServerUseWindowsAuth">
      <Text>Use Windows authentication</Text>
</Control>

10. SQL kasutaja konfigureerimine

Wix SQL skeemi  (Sql Schema) kuuluvate SQL korralduste käivitamiseks tuleb eelnevalt defineerida SQL kasutaja. Selleks on Util skeemi kuuluv User element:

User elemendi lisamiseks tuleb muidugi lisada ka viide WixUtilExtension dll-ile ja üks dokumenteerimata probleem: Wix teeki tuleb lisada ka util nimeruum:

xmlns:util=”http://schemas.microsoft.com/wix/UtilExtension”

Juhul, kui Wix on korrektselt installeeritud, siis pakub VS intellisens seda skeemi ka skeemide loetelust.

Edasi saab kasutaja viite tekitada näiteks:

<util:User Id=”SQLUSER” Name=”[SQLUSERNAME]” Password=”[SQLPASSWORD]“/>

[ ] sees on siis muutujad (Property), mille väärtus võib tulla näiteks omakorda vormist.

Juhul, kui kasutajat ei ole vaja tekitada, siis ei tohi seda panna Component teegi sisse.

Siiski ei ole SQL baasi külge ühendumine nii lihtne. Nimelt ei ole võimalik ei util:User ega ühegi sql nimeruumi kuuluva elemendi puhul määrata, kas kasutada Windowsi autentimist või SQL serverisse sisse ehitatud autentimist. util:User puhul kasutajanime ja parooli tühjaks jätmine ei pane aga sql nimeruumi elemente kasutama vaikimisi Windows autentimist – mis on ka loogiline (by-the-spec programmeerija seisukohalt muidugi, kes ütleks “aga kui kasutajal ongi parool tühi??”).

Ainuke võimalus on teha nii:

  1. Loo muutujad (Property) SQL serveri aadressi, andmebaasi nime, kasutajanime, parooli ja autentimisviisi lipu jaoks, nt. SQLSERVERADDRESS jne. (kui ei ole teisiti öeldud, siis edaspidised koodilõigud käivad kõik Product teegi alla, suvalises järjekorras. 
    <Property Id=SQLSERVERADDRESS/>
    <
    Property Id=SQLSERVERDATABASE/>
    <
    Property Id=SQLUSEWINDOWSAUTH/>
    <
    Property Id=SQLUSERNAME/>
    <
    Property Id=SQLPASSWORD/>
  2. Loo üks util:User, millele määrad vaid Name ja Password peale Id. 
    <util:User Id=SqlUser Name=[SQLUSERNAME] Password=[SQLPASSWORD]/>
  3. Loo kaks sql:Database elementi Product alla, anna neile erinevad Id-d. Ühele neist määra User parameeter, viitama loodud util:User elemendile – see on siis SQL parooliga autentimiseks. Teisel sql:Database elemendil jäta User loomata. Muus osas on nad identsed.
     <sql:SqlDatabase Id=SqlDatabaseWinAuth
              
    Database=[SQLSERVERDATABASE] Server=[SQLSERVERADDRESS]/>
    <
    sql:SqlDatabase Id=SqlDatabasePassAuth
              
    Database=[SQLSERVERDATABASE] Server=[SQLSERVERADDRESS] User=SqlUser/>
  4. Loo kaks komponenti (Component) eraldi Windows autentimise teel ühendumiseks ja SQL kasutajanime/parooli abil autentimiseks. Component teegid muidugi paiguta väljapoole Directory teeke, otse Product alla. Anna komponentidele erinevad Id-d, näiteks SqlUpdateWinAuth ja SqlUpdatePassAuth. Kahjuks tekitab aga see lahendus probleeme komponendi GUID-idega – need peavad olema erinevad ja hiljem võib uuendustel tekkida nende kontrollil lisatööd (hetkel ei tea küll, kus) – aga ehk ka mitte … (NB! Allpool olevas näites on ära jäetud SqlStringide kõik muud atribuudid, mis reaalses koodis on vajalikud.
     <Component Directory=TARGETDIR
              
    Id=SqlUpdateWinAuth >
                <
    sql:SqlString SqlDb=SqlDatabaseWinAuth/>
            </
    Component>
            <
    Component Directory=TARGETDIR
              
    Id=SqlUpdatePassAuth>
                <
    sql:SqlString  SQL=create table a (bb int not null)
              
    SqlDb=SqlDatabasePassAuth/>
            </
    Component>
  5. Kirjuta oma komponentidesse sql:SqlScript elemendid, mis viitavad samale sql skriptile või siis sql:SqlString elemendid (viimasel juhul muidugi pead SQL käsud dubleerima). Ühele määra SqlDb parameetriks SQL parooliga autentiv sql:SqlDatabase, teisele Windows põhise autentimisega (vt. eelmise punkti näide).
  6. Kummagi komponendi jaoks loo Feature, millel määra Display=”hidden” – sa ei taha, et need oleks kasutajale näha. Lisa kummalegi vastavalt eelnevalt loodud komponendid.
            <Feature Display=hidden
              
    Id=SqlUpdateWinAuth Title=With Windows Auth
              
    Description=Install updates with win Auth Level=1>
                <
    ComponentRef Id=SqlUpdateWinAuth/>
            </
    Feature>
            <
    Feature Display=hidden
              
    Id=SqlUpdatePassAuth Title=With Password Auth
              
    Description=Install updates with pass Auth Level=1>
                <
    ComponentRef Id=SqlUpdatePassAuth/>
            </
    Feature>
  7. Ja nüüd jääb teha viimane samm – kuigi Feature on hidden, siis vältimaks selle “installeerimist” tuleb üks neist eemaldada. Selleks võib panna Sql dialoogi Next nupu alla teated (Event) mille tüübiks on Remove (Event=”Remove” ja Value=”featuur, mida pole vaja”). Teisi standardseid teateid (Event) vt. Wix manuaalist.
    <Publish Event=Remove 
     
    Value=SqlUpdateWinAuth><![CDATA[SQLUSEWINDOWSAUTH <> "1"]]>
    </
    Publish>
    <
    Publish Event=Remove 
    Value=SqlUpdatePassAuth>SQLUSEWINDOWSAUTH = “1″
    </Publish>

11. Sql kasutaja kontrollimine

Kui oled loonud dialoogi, milles on väljad SQL serveri andmete küsimiseks, siis oleks hea lisada ka “Test connection” nupp, et installeerimine ei katkeks, kuna kasutaja sisestas kogemata valed andmed. Kahjuks ei ole sql nimeruumis ega üheski muus nimeruumis selliseid võimalusi. Muidugi on olemas laiendamisvõimalused:

  1. luua CustomAction, mis käivitab Win32 DLLis etteantud meetodi. Win32 dll eeliseks on see, et kaasates msi C päised, saab Win32 DLL otseselt kirjutada msi muutujatesse (Property). Puuduseks on see, et tuleb osata C++ keelt ja mitte ainult – tuleb osata ka reaalne kooditükk valmis kirjutada.
  2. kirjutada CustomAction, mille sisuks on JScript või VBScript. Kuid lisaks keele oskamise vajadusele tekib selle lahenduse puhul probleem arvutites, kus on viirusetõrje. Viirusetõrjeprogrammid peavad MSI-d lisatud skriptiga viiruseks ja keelavad MSI käivitamise.
  3. Kirjutada CustomAction .NET-is, exena (soovitav on teha WinForms rakendus, kui MSI kasutab UI-d ja konsoolirakendusena, kui MSI ei kasuta UI-d). Nimelt UI-d kasutav MSI vilgutab konsoolirakenduse puhul ikkagi akent. Eeliseks on, et laiendust on .NET programeerijal lihtne luua, vajalik kood on suure tõenäosusega olemas nagunii. Kuid suurimaks puuduseks on võimatus anda MSI-sse tagasisidet muutuja näol (System.Environment.Exit(<kood>) ei kvalifitseeru, sest !=0 puhul teatab MSI, et viga on fataalne ja kogu paigaldus lõpetatakse. Kuid nt. SQL parameetrite kontrolli puhul peab andma kasutajale vaid teada, et ühendus õnnestus/ei õnnestunud).

Soovitav on siiski kasutada varianti 3, kuna loodetavasti kirjutatakse siiski ka WiX parem .NET CustomActioni tugi. Kuigi hetkel on Microsofti MSI meeskond esitanud hulk argumente .NET CustomActionite vastu, mis seisnevad peamiselt selles, et välised rakendused kujutavad MSI stabiilsusele riski, võiks see siiski olla mingil määral kasutaja valik. Nimelt ka antud näite kohane lihtne SQL parameetrite kuontroll on “MSI invariantne” ehk ei installi ega eemalda midagi.

Seega, kirjutasin .NET WinForm rakenduse (kasutades vaid System.* nimeruumi, et ei tekiks sõltuvusi teistest .NET teekidest) WinWixSQLCheck.exe, mis loeb käsurealt argumendi kujul Sqlserver=<server>|Sqldatabase=<andmebaas> jne. ja käivitan selle Wix CustomActionina:

<Binary Id="WixChecker" SourceFile="Binaries\WinWixSQLCheck.exe"/>
<CustomAction Id="CheckSql"
            BinaryKey="WixChecker"
            ExeCommand="Username=[SQLUSERNAME]|Password=[SQLPASSWORD]|Sqlserver=[SQLSERVERADDRESS]|Sqldatabase=[SQLSERVERDATABASE]|Usewinauth=[SQLUSEWINDOWSAUTH]"
            Return="check" />
us: 
  1. Eelnevalt laen WinWixSQLCheck.exe MSI-sse binaarse lisana Binary teegi abil (Binaries on projekti alamkataloog)
  2. ExeCommand on käsurea argument

Ja edasi käivitan kontrolliva exe näiteks “Test connection” nupu abil:

<Control Type="PushButton" Width="78" Height="17" X="248" Y="169"       Id="SqlTest">
      <Text>Test connection</Text>
      <Publish Property="SQLTEST" Value="1"/>
      <Publish Event="DoAction" Value="CheckSql">1</Publish>
</Control>

Event DoAction ongi CustomActioni käivitamiseks, Value=CheckSql on tegevuse nimi. Publish Property=SQLTEST on aga vajalik selleks, et lubada Next nupu vajutamine (mida Next nupp loeb).

12. Windows teenuste (Service) paigaldamine

Võrreldes eelnevaga on see tõeliselt lihtne. Tuleb luua komponent, milles defineeri teenus, ning valmis see ongi:

<Component Id="NewsletterService"  Directory="TARGETDIR">   <File KeyPath="yes"
                Id="ServiceExecutable"
                Source="Artifacts\<serviceexe>.exe"
                Name="<serviceexe>.exe" Vital="yes"/>
            <ServiceControl Id="StopNLS"
                Start="install"
                Remove="uninstall"
                Stop="install" Name="<servicename>"/>

<ServiceInstall
                ErrorControl="normal"
                   Description="<service desc>"
                DisplayName="<service disp name>"    Id="InstallNLService"
                Name="<servicename>"
                Type="ownProcess"
                Start="auto" Vital="yes"/>

</Component>

Kus:

  1. Teenuse exe peab olema Component teegi esimene alamelement ning Keypath=yes – ServiceInstall element eeldab seda.
  2. Servicecontrol teek kirjeldab, kuidas käituda installeerimisel ja eemaldamisel ja kas/millal teenus käivitada

13. Uuenduste loomine

Uuenduste tegemise hõlbustamiseks kasutan WiX kompilaatori muutujaid, kus defineerin toote versiooni ja ID-d. Lisada Wix teegi alla definitsioonid:
<!– when you make upgrade, then increment Version numbers as
        needed and ALWAYS change SetupProductCodeGuid and SetupPackageCodeGuid
        DO NOT modify SetupPackageUpgradeGuid unless you do not want old product be upgradable anymore
–>  
    <?
define SetupProductMajorVersion=”0″?>
    <?
define SetupProductMinorVersion=”0″?>
    <?
define SetupProductBuildVersion=”5″?>
    <?
define SetupProductCodeGuid=”DEE9008F-00A5-4f4c-85C1-560BE483E7FC”?>
    <?
define SetupPackageCodeGuid=”7BDEC0DA-5339-4b1e-8507-F97948F36A21″?>
   
    <?
define SetupPackageUpgradeGuid=”C72056CC-97EC-479F-ADF5-323EABD35D56″?>

Edasi kasutan toote, paketi ja versiooni koodidena neid muutujaid:

<Product Id="$(var.SetupProductCodeGuid)"
Peale Package teeki lisan:
<InstallExecuteSequence>
            <RemoveExistingProducts Before="InstallInitialize"/>
        </InstallExecuteSequence>

Edasi defineerin Updgrade bloki:

<Upgrade Id="$(var.SetupPackageUpgradeGuid)">
            <UpgradeVersion
                Minimum="0.0.0"
                IncludeMinimum="no"
                Maximum="$(var.SetupProductMajorVersion).$(var.SetupProductMinorVersion).$(var.SetupProductBuildVersion)"
                IncludeMaximum="no"
                Property="OLDERVERSIONBEINGUPGRADED"/>
            <UpgradeVersion OnlyDetect="yes"
                Property="NEWVERSIONDETECTED"
                Minimum="$(var.SetupProductMajorVersion).$(var.SetupProductMinorVersion).$(var.SetupProductBuildVersion)"
                IncludeMinimum="no"/>
        </Upgrade>

 

14. Visual Studios tekib Wix projekti avamisel viga “…. HRESULT E_FAIL …”

Ma ei tea küll vea tegelikku põhjust, sest tegu on väga üldise veaga, kuid viga peitub mingil moel rikutud wixproj failis. Kuid milles, on samuti müstiline – nimelt tekitasin ma uue projektifaili, mis avanes korrektselt. Seejärel võrdlesin WinMerge abil töötavat ja vigast projektifaili, kuni leidsin, et viga kaob, kui projektifailist eemaldada teek WixExtension Include=”WixUIExtension”. Kusjuures omapärane on see, et teise loodud projekti WixUIExtensioni lisamisel ei tekkinud endiselt probleeme. Kuid samas tekkis viga isegi siis, kui korras projektifailist tõstsin selle teegi WinMerge abil üle.

Lahendus: kustuta käsitsi projektifailist kogu ItemGroup, kus on Extension teegid, ava projekt VS-s ja lisa referentsid uuesti.

ID kaardi põhise autentimise seadistamine IIS 6.0-s

aprill 15, 2008 kirjutas neemevool

Kirjutamise põhjuseks on www.id.ee peal olev eksitav juhend: http://www.id.ee/10456?id=10737 . Selle juhendi üle on kaevanud ka teised: http://dukelupus.wordpress.com/2006/12/24/tants-id-kaardi-umber-ehk-iisi-ja-id-kaardi-suhtlema-panemine/

Kuna samuti kulutasin selle “üllitise” järgi IIS 6.0 konfigureerides mitu tundi oma aega, siis kirjutan teise versiooni sellest.

Siiski, ma ei ole testinud seda lahendust kõikidel Windows serveri platvormidel, tegin selle läbi Windows Server 2003 R2, Standard Edition, Service Pack 2 peal.

1. Installeeri IISi SSL tugi. SSL on vajalik, IIS ei aktiveeri kliendilt sertifikaatide küsimist üle HTTP.

Selleks:

a) osta, generereeri või hangi testsertifikaat. SSL sertifikaatide pakkujaid on väga palju ja hinnad on väga erinevad. Erinevused tulevad peamiselt sellest, kas SSL sertifikaadi pakkuja on kõigis enamlevinud brauserites registreeritud või mitte. Lisaks muud “äriteenused” ja “võimalused”, nagu näiteks “wildcard SSL” jms. Ise ostsin SSL sertifikaadi Thawtelt, sealtsamast saab ka 21 päeva kehtiva ajutise sertifikaadi. Thawte ostu protsess on samuti kõige arusaadavam.

b) kuidas täpselt SSL sertifikaati IISi paigaldada, võib lugeda kahte allikat kombineerides: Thawte lehelt dokumendist https://www.thawte.com/ucgi/gothawte.cgi?a=w44600158747054000 (Securing your Microsoft Internet Information Services (MS IIS) Web Server with a thawte Digital Certificate ja raamatust Microsoft IIS 6.0: Administrator’s Pocket Consultant, William R. Stanek, ISBN: 0735615608. Viimati nimetatud raamatus peatükk 8 on väga lakooniline ja samas täpne.

2. Kontrolli, et IIS suudab üle HTTPSi serveerida.

3. Lae Sertifitseerimiskeskuse lehelt alla sertifikaadid: http://www.sk.ee/pages.php/0202040501 

Sul on vaja PEM formaadis sertifikaate: Juur-SK, ESTEID-SK ja ESTEID-SK 2007. Ava Notepadis uus tekstifail, ja copy-paste sinna üksteise järel samas järjekorras sertifikaatide sisu. Faili nimi ei ole oluline, võib olla näiteks ESTIDCompl.PEM.cer.

Ka faili laiend ei ole oluline, kuid kui annad laiendiks .cer, siis on võimalik sertifikaat kohe ka topeltklikiga installeerida. Sertifikaatide installeerimiseks pead olema sisse loginud administraatorina.

Kindlam viis on sertifikaadid installeerida Windows Serveri halduskonsoolis, selleks:

a) Start->Run, kirjuta mmc, OK. Avaneb tühi konsool.

b) konsoolis vali File->Add/Remove Snap In, avanenud aknas vajuta nuppu Add…

c) avanenud uues aknas vali nimekirjast Certificates, vajuta Add. Avaneb uus aken, kus vali Compute account. Finish, Close.

d) vajuta järelejäänud aknas OK.

e) Halduskonsooli tekitati Certificates puu, kus ava Trusted Root Certification Authorities ja parema hiire klikiga vali selle peal All Tasks -> Import. Vali see kokku pandud fail (meie näites ESTIDCompl.PEM.cer).

Juhul, kui oled eelnevalt id.ee eksliku juhendi järgi katseid tehes oma sertifikaatide lao segi keeranud (installeerinud neid kõikidesse kohtadesse vms.), siis otsi üles just paigaldatud ESTIDCompl.PEM.cer-st tekkinud sertifikaat ja selle peal nimekirjas Properties aknas võid anda talle mingi sobiva Friendly Name.

4. Ava IIS halduskonsool, vali veebisaidi, millele soovid ID autentimist rakendada omadused (Properties). Kaardilt Directory Security (mis peaks juba tuttav olema, kuna sealt paigaldasid ka eelnevalt SSL sertifikaadi) vajuta osas Secure Communications nuppu Edit …

a) võid märkida valikukasti Require secure channel – kuid ID kaardiga autentimiseks ei ole see kogu saidile vajalik.

b) vali Client certificates alt vähemalt Accept client certificates (arusaadavatel põhjustel ei ole mõtet valida Ignore …)

c) Tee linnuke valikukasti Enable certificate trust list. Kui sul veel ei ole ühtki, siis vali New. Avanenud viisardis vajuta nuppu Add From Store, kus avanenud aknas lisa hiljuti lisatud ESTID failist tehtud sertifikaat (tunned selle ära näiteks eelnevalt antud Friendly Name järgi – kui oled eelnevalt juba importinud id.ee juhendi järgi, siis vale valiku tegemisel ei hakka autentimine tööle).

Juhul, kui kasutad test-SSL sertifikaati, siis pead valima lisaks ka juursertifikaadi SSL jaoks (mina näiteks Thawte Test CA Root).

Certificates in the CTL ehk Certificate Trust List loetleb JUURsertifikaadid, mille sertifikaate aktsepteeritakse.

5. Edasi võid ID kaardiga autentimiseks valida mitmeid tehnikaid – kuid, sa ei pea sugugi kõiki faile tingimata kaitsma ID kaardi autentimisega. Piisab, kui su lehel leidub üks fail, nt. login.aspx, mille puhul nõutakse autentimist ja login.aspx seab püsti juba sessiooni, näiteks cookie põhise. Edasi teised failid kasutaks siis juba enda loodud sessiooni. See on otstarbekas näiteks siis, kui lehel saab mitmel moel autentida.

6. Login.aspx ID autentimist küsima panemiseks vali IIS halduskonsoolis veebisaidi failide nimekirjast Login.aspx ja parema nupuga kuva omadused ehk Properties.

a) vali File Security kaart, sealt Secure Communications osast vajuta Edit …

b) Tee linnuke valikukasti Require secure channel (SSL)

c) Client Certificates osast vali vähemalt Accept client certificates. Sa ei pea valima Require client certificates, sest juhul, kui kasutaja keeldub ID kaardiga autentimast, peaksid saama endiselt pakkuda kasutajale alternatiive, mitte keelduma näitamast login lehekülge.

7. Nüüd jääb teha veel saidipõhine autentimis- ja sessioonilahendus. Väga lihtne näide, kuidas ilma sertifikaadi aegumist kontrollimata lugeda aspx failis isikukood ja nimi:

if (Request.ClientCertificate["Subject"].Length == 0)
        {
            Response.Write(“Ei antud sertifikaate”);
        }
        else
        {
            String unparsed=Request.ClientCertificate["Subject"];
            System.Text.RegularExpressions.Regex re = new Regex(“SERIALNUMBER=(\\d{11})”);
            Response.Write(“<br/>unparsed:” + unparsed + “<br/>”);
            if (re.IsMatch(unparsed))
            {
                String idcode = re.Match(unparsed).Groups[1].Value;
                Response.Write(“Su isikukood on:” + idcode + “<br/>”);
            }
            System.Text.RegularExpressions.Regex rename = new Regex(“SN=(.*?),\\s+G=(.*?),”);
            if (rename.IsMatch(unparsed))
            {
                String eesnimi = rename.Match(unparsed).Groups[1].Value;
                String perenimi = rename.Match(unparsed).Groups[2].Value;
                Response.Write(“Su nimi on: “+eesnimi+” ” +perenimi+”<br/>”);
            }
        }