Vítejte na blog.vyvojar.cz Přihlásit | Registrovat | Pomoc

Webground

ASP.NET 2.0, Microsoft SQL Server, SEO etc.
Globální přihlašování - "Single Sign"

Při dokončování posledního webu mě napadla věc a to, že by to možna na těch 15 webů chtělo jednotné přihlašování. Nemyslím jen jednotné jméno a heslo a jeden web, který by to vše obstarával. Hlavní důvod byl ulehčit uživatelům, webů je spoustu a jsou silně propojené (kvůli SEO), takže jsem chtěl, aby se uživatel přihlásil jen jednou (tzn. i pokud na webu ještě nikdy nebyl, ale přihlásil se na jiném z našich webů bude přihlášen). Postup mých myšlenek:

  • Session  - údaje o uživateli jsou uloženy v session, které jsou oddělené pro každou aplikaci. Našel jsem pár článků, jak si session nasdílet když používáte pro ukládání session SQL Server, to bohužel nevyšlo, protože uživatel pokaždé dostal úplně jiné session ID a nenapadal mě způsob jak vždy vygenerovat pro daného uživatele stejné ID a zároveň udržet ID natolik unikátní, aby se uživatelé přistupující např. z jedné IP netloukli.
  • Cookies - cookies byly částečným řešením, díky vlastnosti Domain u objektu HttpCookie lze cookie nasdílet pro subdomény, tzn. pokud jako hodnotu vlastnosti domain zadáte ".example.com" budou mít všechny weby na subdoménách něco.example.com ke cookie přístup. Kdyby každý náš web neměl úplně jinou doménu, bylo by to fajn...

Nápad s cookies vypadal slibně, jen bylo potřeba sjednotit tak, aby cookies vždy kontroloval jeden web a požadavek vysílal uživatel sám, protože server nebude mít unikátní identifikátor. Po pár minutách vylezl celkem šílený nákres, snad to popíšu srozumitelně:

Jsou založeny dva weby - web s obsahem (CW) a web, který zajišťuje přihlašování (LW). Cesta začíná na nějaké stránce na CW, kam se vloží jednoduchý control podobný LoginView. Tento control zkontroluje zda existuje session, pokud ne, zobrazí obě části controlu - template pro přihlášeného a nepřihlášeného uživatele, pokud ano, rovnou vyrenderuje část pro přihlášeného uživatele. Do stránky se se vloží element script, který ma jako adresu scriptu zadaný handler, který je částí LW. Tento handler zkontroluje svou session a vygeneruje odpovídající javascriptový kód. Pokud není session nalezena, vygeneruje se script, který skryje na CW část pro přihlášeného uživatele. Naopak pokud je nalezena, vygeneruje se script, který skryje část pro nepřihlášeného uživatele a do části pro přihlášeného doplní jméno atp. a hlavně nalinkuje opět pomocí elementu script handler umístěný na CW, který dostane pomocí QueryStringu ID uživatele a do své session uloží informace o uživateli. Je dobré zavolat handler i při nenalezení uživatele a dát tak aplikaci vědět, že uživatel přihlášen není, aby se zbytečně neustále CW neodkazoval na LW. Při jakémkoli dalším požadavku je už uživatel v session daného webu nebo aplikace o jeho nepřihlášenosti ví, takže se tato šílenost už neopakuje.Přihlašování je nutné dělat přes LW, nebo ho alespoň o přihlášení upozornit. 

Volání handlerů pomocí elementu script je vlastně forma ajaxu, což můžete uskutečnit klidně pomocí XmlHttpRequest, ale toto funguje napříč všemi prohlížeči...
 

Určitě bude ještě potřeba kvůli použití QueryStringu ID sifrovat a opatrit nějakým kontrolním hashem, protože je to celkově dost náchylné. Teď se určitě najde někdo, kdo bude mít 100x lepší nápad, než je tato bláznivina...sem s ním Smile

Ať žije O2Off

Pokud máte nějaké problémy s O2 doporučuji si přečíst blog člověka, který ve zdraví přežil odchod od zmíněného operátora. Nedávno jsem podobné martirium také absolvoval (i když naštěstí v mnohem menší míře).

Potřeboval jsem nový telefon, měl se jím stát HTC TyTN II (Kaiser), který má T-Mobile za celkem dobrou cenu. A vzhledem k tomu, že nabízí datové zvýhodnění Surf+Mail za necelé dvě stovky bez daně z měsíc, tak jsem se rozhodl přejít.

První krok po tom, co jsem dal dohromady peníze byla objednávka u T-Mobilu. Na strankách tmobile.cz jsem zjistil, že nákup přes e-shop má nespoet výhod, tudíž jsem se o něj pokusil. Vyplňování tuny formulářů začalo celkem bez problémů, dokud jsem se nedostal k části přenesení čísla. V zájmu ochrany svého webu je omezeno zažádání o přenesení čísla na tři žádosti denně, což by nevadilo, kdyby zprávy nedorazily o deset hodin později než měly. Po třech pokusech už mě web posílal do dálných končin, takže jsem začal prohledávat sekci podpora a najednou "žuch") a stránky přestávaly fungovat, objevovala se božská 404 chyba, která se po pár zdrcení F5 u některých stránek sama napravila (fakt nechápu jak dotyčný vytvořil ten HttpModule na url rewriting).  Další kroky vedly do sekce  Napište nám, která se bez problémů načetl, v zájmu matení nepřitele, protože aplikace vybuchla až při postbacku, takže jsem měl smůlu. Následoval e-mail do T-Mobilu, kde jsem váhal, zda mám přecházet k operátorovi, který si nemůže dovolit pořádného .NET developera.

Druhý den dorazila odpověď, že má stížnost byla předána na vývojové oddělení a že v době kdy e-mail dorazí bych měl mít k dispozici další tři pokusy o přenesení čísla. Tentokrát již vše fungovalo, takže špatná nálada byla ta tam a já se těšil na nový telefon. Po třech dnech dorazil kurýr PPL s pořádnou krabicí, na místě jsem podepsal smlouvu a bylo hotovo. Telefon byl neblokovaný, takže jsem mohl začít používat nový přístroj i se starou simkou, super!

Druhý krok je výpověď u stávajícího operátora - O2, zde začala ta vtipnější část. Při podávání výpovědi se mě slečna snažila přesvědčit co mohla, ale viděla, že mám v ruce už nový telefon a když jsem řekl, že už mám podepsanou smlouvu, tak to vzdala. Na stávajícím čísle u O2 jsem měl závazek ještě rok, takže jsem musel zaplatit pokutu (rozdíl ceny z minulého telefonu), poplatek jsem chtěl zaplatit hned na místě, protože mi to připadalo jako nejrychlejší cesta se jich zbavit, poté po mě slečna žádala 1850 Kč (očekával jsem 1800 Kč, což mi řekli při předchozí navštěvě) tudíž jsem se zeptal, za co je těch 50 Kč, teď přijde ta chuťovka, je to pokuta za to, že platím v hotovosti. No co jsem měl dělat, zaplatil jsem. Při vyplňování výpovědi se mě ještě ptala na důvody, uvedl jsem, že konkurence má výhodná data, která mi oni nabídnou nemohou. Opáčila, že mě o tom už teď nebude přesvědčovat. Odpověděl jsem, že jestli je mohou nabídnout, tak ať si je laskavě nechají, protože jsem se tam chodil snad každý měsíc na toto téma ptát.

Zbytek rodiny má čísla stále u O2. Další faktura obsahovala skvělé překvapení - položku za 1800, zmíněnou pokutu. Což mi tatík hodil na stůl, ať si to vyřeším, takže jsem volal na 800 02 02 02 a snažil se prodrat k operátorce (bylo to v sedmé podsekci když nepočítám volbu jazyka). Ta mi sdělila, že ona platbu vidí ale jejich systém si ji nevšiml a automaticky zkompletoval fakturu takto, ať se o to nestrachuji a nevšímám si toho. Dva dny po tomto hovoru dorazily zbytku výhružné smsky s tím, že O2 dlužíme 1800 Kč a pokud je nezaplatíme, tak budou čísla odpojena, přičemž už všem došla trpělivost a já si šel opět zařvat na O2. Silným tónem jsem jim vytvětlil, že umí pouze vyhrožovat a buzerovat a že by si měli pořídit lepší systém, potažmo lepší vývojáře (nechápu, že takto velké společnosti nemají na kvalitní developery). Konec pohádky, mám nový telefon, O2 dalo pokoj, čekám na první fakturu od T-Mobilu, tak jsem zvědav...

Developer Days 2007

Letos Microsoft opět uspořádal očividně oblíbenou akci Developer Days (zvýšený zájem byl nejspíšě způsoben tím, že akce byla tentokrát zdarma Smile)

Viděli jsme:

  • Ukázku aplikace evidence pacientů, do které můžete přistupovat ze smartphonu nebo notebooku ať on-line nebo off-line (demonstrace módy univerzálních aplikací, ale neodpustím si: kdy jen přijdou doby, kdy si český lékař bude moci dovolit moderní notebook nebo smartphone s neomezeným připojením...)
  • Silverlight na sto způsobů (tuto přednášku bylo možné navštívit na jaře v Microsoftu - přednášel Štěpán Bechyňský), ve verzi 1.0 docela nuda, 1.1 bude o dost zajimavější
  • Technologii LINQ
  • ASP.NET AJAX (velikostí javascriptu, který s sebou neustále taháte se nikdo nechlubil...jako obvykle), přednáška kvalitní, ne jako minulý rok, kdy všechny uprostřed snu o krásné aplikaci bez chyb vzbudil mobil
  • Služby dostupné prostřednictví http://dev.live.com (některé jsou docela použitelné, jen kdyby začalo mít msn nějaký slušný podíl, i když se v MS snaží, google má pořád něco do sebe)
  • Nové Visual Studio 2008 a integrovaný systém pro testování webových aplikací (na DVD jsme dostali trial verzi, mela by tedy byt i na netu)
  • Vylosování šťastlivce, který vyhrál Xbox 360 (dobrý způsob, jak udržet téměř celý sál až do konce - poslední přednáška byla o MS Expression studiu, grafiků bylo na akci cca 1%), měli jsme také možnost si na Xboxu zahrát Halo 3, hrát střílečku na gamepadu se mi zdálo dost ujeté, ale "prej to jde"
  • Poznámku k tomu, že p.Bechyňský usnul na přednášce D.Krčmáře (to fakt neměl dělat :))
A nakonec jedna perlička (DevDays Praha) - Microsoft vybavil autobusy, které odváželi ráno od metra k místu konání, po skončení akce naopak. To by nebylo nic divného, až do té doby, kdy se objevil normální autobus MHD, do kterého se začal dav nekompromisně soukat (pohled řidiče autobusu když spatřil ten dav nezapomenu) načež všichni uvnitř zjistili, že tenhle bus zadarmo nejede a začali lovit jízdenky. Po chvilce čekání se objevil očekáváný autobus s označením Microsoft Developer Days, do kterého se vším pohodlím nastoupilo 9 lidí (počítal jsem to). Cestou jsme potkali jednu dvojici, která se rozhodla jít pěšky a zkoušela styl prošení "psí oči", což na řidiče příliš nezapůsobilo. Korunu tomu ale nasadila scéna, kdy přecpaný bus zastavil na zastávce, my jej předjeli a za velkého jásotu zamávali kolegům, kteří se tiskli jako sardinky.
Šifrovaný QueryString

V administraci svého CMS jsem potřeboval zašifrovat QueryString, aby nějakého chytráka nenapadlo si změnit ID položky a editovat cizí web, zpočátku jsem to řešil jednotlivým šifrováním hodnot, to se ale příliš neosvědčilo, každá hodnota se musela šifrovat zvlášť, nebyly použitelné vestavěné controly jako HyperlInkField atd. Na webu http://www.antoniob.com/ jsem našel zajímavější řešení které mělo pár vad - 1) bylo vytvořené v Delphi, takže jsem musel vždy doplnit ještě dvě další knihovny které rozchodily delphi 2) autor tam má menší chybu, stránka se nevypisuje celá (šifrované URL jsou někdy delší než původní a počet znaků který nabyde u adres potom zmizí na konci stránky - typicky je tam javascript na validátory, který pak samozřejmě nefunguje).

 

(Pozn. obrázek převzat z výše uvedeného webu)

 

Další example jsem již našel v C# zde, bohužel obsahoval pouze horní polovinu postupu, nezvládal upravovat adresy ve stránce, také neumožňoval nastavení vlastního hesla a názvu parametru (v kódu bylo možné obojí přehledně změnit, ale v assembly už těžko). Takže hurá do toho... Teď je již komponenta kompletní filtruje všechny linky (pomocí regulárních výrazů hledá všechny atributy href a pokud směřují do vlastní aplikace a mají nějaké hodnoty v query stringu, tak jsou zašifrovány. Také se šifruje query string u atributu action u tagu form.

Implementace 

Stačí pouze přidat tento kód do sekce system.web ve vašem Web.Configu

    <httpModules>
        <add type="EncryptedQueryString.QueryStringModule" name="QueryStringModule" />
    </httpModules>

 V zipu nazelnete zdrojový kód a assembly. Do Web.Configu ještě můžete doplnit do sekce AppConfig dvě možnosti - "EncryptedQueryString_Key" což je klíč podlě kterého se budou query stringy šifrovat (používá se algoritmus Rijndael), výchozí hodnota je nějaká změt znaků (bouchnul jsem do klávesnice :)) a druhá je "EncryptedQueryString_ParamName" což je název paramteru který vidí uživatelé - např. MyPage.aspx?ParamName=zasifrovana_hodnota, výchozí hodnota je "Hidden=" (hodnotu musíte zadat i s rovnítkem)

 

Texy! prelozena pro .NET (aktualizováno)

Dnes jsem dosáhl základního tábora při převodu Texy! do .NET. Zatím mám úspěch pouze s verzí 1.1, protože verze 2.0 vyžaduje určité funkce, které přímo ve Phalangeru nejsou, budu je muset dotvořit. Pokud by se nějaký PHPkář hlásil dobrovolně do služby, ozvěte se, vidím to podruhé v životě Big Smile Každopádně gratuluji tvůrců Phalangaru, odvedli opravdu skvělý kus práce.

Další aktualizace zítra (teda spíše dneska). 

 

to Tomas: nakonec jsem tvuj clanek taky nasel (bohuzel az po par hodinach zoufalstvi :) Verzi 1.1 jsem rozchodil bez modifikaci, funguje, funkce process vraci XHTML, parada, ale verze 2.0 po kompilaci a zavolani tridy dostanu v C# chybu "Exception has been thrown by the target of an invocation." takze php nekde vraci chybu, po chvilce nalezeno:

{"Could not load file or assembly 'php4ts, Version=2.0.0.0, Culture=neutral, PublicKeyToken=43b6773fb05dc4f0' or one of its dependencies. Spuštění této aplikace se nezdařilo, protože konfigurace aplikace není správná. Tyto potíže lze pravděpodobně vyřešit opakovanou instalací aplikace.  (Exception from HRESULT: 0x800736B1)":"php4ts, Version=2.0.0.0, Culture=neutral, PublicKeyToken=43b6773fb05dc4f0"}

co s tim??? extisuje ta knihovna ve forme, aby se dala nacpat pri kompilaci do assembly?

funkce o ktere jsem mluvil byla iconv (o pulnoci jsem byl uz trosku slepy),  s tim uz problem neni.
 

Webground Controls ke stažení

Konečně jsem se dokopal k publikování balíku controlů, naleznete ho na http://www.codeplex.com/webground. Nakonec je přibaleno trochu víc - přibyl nový namespace, který obsahuje vše potřebné pro URL rewriting (je možné pravidla skladovat i v MS SQL DB). Dále plánuji vytvoření vlastního Membership provideru, vestavěný děla dle mého v DB trochu "bugr". Čekám sprchu kritiky, tak do toho....

 

Pokud máte nějaké nápady na zlepšení, nové controly atp., určitě napište 

Vývoj webu legálně a zadarmo

Poslední číslo časopisu Computer se jako každý rok zabývalo jak ušetřit peníze pomocí freeware aplikací v různých směrech, já se o totéž pokusím ve směru vývoje webů, protože tato část byla bohužel opomenuta.

1. Design

Pokud to budete myslet s grafikou a designem do budoucna vážně, stejně asi koupi Photoshopu nebo Corelu neuniknete, na druhou stranu, pokud jste programátor a obrázky jen občas potřebujete doladit, popř. provést klasické úpravy jako ořezání, zmenšení atp. je zbytečné riskovat (pokud máte nelegální verzi) nebo vyhazovat peníze (pokud chcete program koupit/jste to už udělali), protože na tyto úkony je dle mého 20 tis. za jednu licenci silné vyhazování.
V této kategorii je pro mě favoritem program Paint.NET, který je vyvíjen, jak již název vypovídá, na platformě Microsoft .NET. Z čehož plyne nutnost instalace tohoto frameworku. Velké pozitivum této aplikace je dostupnost velkého množství plug-inů (třeba na otevírání PSD souborů). Ve verzi 3.0 a dále je již možné mít v jednom okně více souborů otevřených současně. Jediná věc, která dle mého pokulhává je velikost souborů ukložených do JPEGu. Program je vyzkoušen i pro Vistu, funguje bez problémů, nové verze vycházejí každou chvilku, tak ho zkuste taky....

Ukázka aplikace Paint.NET

 2. Práce s kódem

 Tato kategorie má alespoň pro mě jasného vítěze a není jím nikdo jiný než express edice Microsoftího Visual Studia - Visual Web Developer. Za ta léta jsem si na toto IDE natolik zvykl, že už bez něj nejsem prakticky schopen napsat jediný řádek kódu a vzhledem ke změnám, které se připravují do nové verze si myslím, že jak na poli placených, tak free aplikací bude jeden z prvních. PHPkáři prominou, ale jejich platforma jde mimo mě, takže s výběrem editoru nepomohu.

3. Databáze

V této oblasti určitě naleznete více rovnocenných hráčů, já vzhledem k cílovému serveru používám Microsoft SQL Server 2005 Express (poznámka pro ty, které následující ještě nenapadlo: i do této edice si můžete zaregistrovat další servery, takže není problém komfortně - určitě komfortněji, než přes Web Admin - spravovat vzdálený SQL Server). Ještě doplním, že v express edici nechybí nástroj export import! Stačí si jen stáhnout největší instalační soubor a ve složce ..\Microsoft SQL Server\90\DTS\Binn naleznete soubor DTSWizard.exe, ve kterém se tento užitečný nástroj skrývá (Doporučuji hodit do External tools).

Za další kvalitní databázové servery bych určitě uvedl Oracle, jehož četnost nasazení se zvyšuje každým dnem a podporuje ADO.NET, takže je pro spolupráci s .NET Frameworkem velmi vhodným kandidátem.

Nakonec ještě zmíním databáze firebird, které jsou velmi praktické tím, že pro jejich použití nepotřebujete žádnou podporu ze strany hostingu (popř. cílového počítače, pokud se jedná o normální aplikaci), na vše stačí pouze jedna dll knihovna. Licence umožňuje redistributable použítí.

4. FTP

Donedávna jsem jako FTP klienta používal Total Commander a to do té doby, než jsem potřeboval přesunout 7800 fotek (max. 20kB na soubor) na FTP. Přenos spadl min desetkrát, navíc se nejednalo o legální program, náhrada se ale našla velmi rychle - FileZila. Umožňuje zařadit soubory do fronty a zmíněný přesun zvládla na první pokus bez jediného výpadku. Jedinou výtku mám pouze k uchovávání hesel - xml soubor není úplně nejlepší nápad, soubor stačí zkopírovat, hodit do svého PC a máte hesla, stejně asi ale nebudete ukládat hesla do PC, u kterého budete dvakrát v životě. Jinak jsem si zvykl celkem rychle a nemám dalších námitek.

 

Znáte nějaké další užitečné programy, které jsou zdarma? Podělte se s ostatními.... 

Programátoři, nebuďte prasata!

Možná jsem použil trošku ostřejší nadpis, ale po tom, co jsem dnes a v minulých dnech shlédl a musel zpracovat mě jemnější výrazy nenapadají. Začal jsem přepracovávat jednu starší aplikaci napsanou v ASP 3.0 přepsat kvůli nevyhovující funkčnosti atd, bylo to potřeba. Při postupném procházení aplikací jsem přišel na tyto perly:

  • Jako databáze je použita Accessová DB, vzhledem k návštěvnosti a hardwaru serveru docela síla ale to ještě není to nejhorší...(cca 2000 denně a přes 20 000 řádků v databázi, v některých tabulkách je přes 60 sloupců, takže dat je dost)
  • Connection string je uložený v souboru s příponou .inc bohužel ale už nikoho nenapadlo nastavit v IIS parsování souborů s touto příponou, takže umístění i heslo k databázi je volně přístupné jako každý jiný textový soubor
  • Způsob ukládání dat v databázi, chuťovka: ke každému uživateli jsou zaznamenávány jazyky, které ovláda zároveň s informací o úrovni znalosti jazyka a to v tomto formatu "^cesky|anglicky#beginner^cesky|anglicky#intermediate", cesky a anglicky je to zde uvadeno kvuli dvema jazykovym verzim webu, jak jednoduché bude asi vytvoření další jazykové mutace? (nebudu komentovat polovinu sloupcu s ciselnymi udaji typu varchar, v Accessu vlastně text a misto bool - ano/ne se standardně používá číslo, proč se ti šílení výrobci db systémů vůbec namáhali...)
  • Registrační formulář má na délku asi metr, takže přišel nápad rozdělit jej na dvě části, dobrý nápad, šeredné ale opravdu hodně šeredné provedení - hodnoty z první části formuláře jsou do druhé a poté k uložení penášeny v session, jak "vývojář" později zjistil, uživatelé nestíhali vyplňovat registraci do vypršení session timeoutu, tak ho nastavil na 4 hodiny, proč tak málo? (asi tři hodiny jsme bloumali proč je po odebrání jednoho paměťového modulu ze servisních důvodů server pomalejší než chtřejší mobil.
  • Session nekončí, další věc bylo otevření informací o uživatelích - výsledek dotazu z DB se uložil ve formě řetězce "aaaa|bbbb|cccc" do session a stránka byla přesměrována, další stránka tento šílený řetězec rozsekávala a vypisovala, složiteji to nešlo?
  • Datový typ datum/čas, nebojte, ani tento typ tento chorý jedinec nezná, ukládá data ve formátu ddmmrrrr což by nebylo zase až tak špatné až na to, že každá jazyková verze má na IIS jiné nastavení Culture, takže jednou funkce vracela ddmmrrrr a podruhé mmddrrrr, co opravdu nechápu je, kde se v DB vzala hodnota ve formátu rrrrmmdd
  • Jak uložit seznam států světa, že by tabulka v databázi? Ha ha, to zrovna, oblíbený řetězec "aaaa|bbbb|ccccc" je zde v plné kráse, v DB se místo ID používá pořadí v poli po použití metody split. Jak asi předpokládáte, potřebuji zhruba doprostřed pár záznamů vložit, jak? Je to jedno, jakýmkoli způsobem na to půjdete, vždycky z toho kouká hromada hodin práce.

O NEkompatabilitě mezi prohlážeči a neznalosti inputu typu password se radši zmiňovat nebudu, hlavní stránku jsem zkusil vložit do validátoru, výpis chyb se načítal pěkně dlouho a nebylo to mým připojením.

Tímto příspěvkem Vás všechny moc prosím, nedělejte tyto a podobné věci!

Díky těmto lidem je sice stále dostatek práce, ale je to o nervy. Už jsem napsal cca 1500 řádků C# kódu Windows forms aplikace, která převádí databázi ze staré "verze" do použitelné podoby.

Přednáška Štěpána Bechyňského:Web 2.0

Dnes jsem byl hostem přednášky Štěpána Bechyňského na téma Web 2.0. Tomuto tématu nešlo odolat, již nějakou dobu tato přefouklá bublina cloumá diskusemi zabývajícími se vývojem webů.

Témata přednášky

  • Web 2.0 - co to je? vcelku předpokládaná ukázka webových aplikacích přizpůsobitelných uživateli, využívajících AJAX atp.
  • Aplikace Microsoft Expression Web
    • velmi praktická aplikace, grafik jásal nadšením, Visual Studio se mu zdá příliš nepřehledné, my ostatní jsme byli bohužel zklamaní, tyto funkce budou ve Visual Studiu až ve verzi Orcas, která by měl prý vyjít "snad tento rok", screenshoty jsou na blogu Scotta Guthrieho
    • zmiňované funkce spočívají v inteligentním a rychlém přiřazovaní tříd objektů, přehled aplikovaných vlastností na objekt, který zahrnuje i dědičnost a přehledně zobrazí, která vlastnost byla z které třídy poděděna a kterou třídou byla popř. přepsána; možnost vložit do stránky klasické ASP.NET 2.0 controly, takže grafik aplikuje css třídy rovnou na control a programátor pak nemusí css předělávat
  • AJAX
    • ukázka zajaxování aplikace, samozřejmě pomocí ASP.NET AJAX 1.0
    • diskuse se opet silne zamerila na znamých a pověstných 300 KB
    • použití webových služeb (pro mě byla docela nová informace, že webové služby musíte psát zvlášť pro AJAX a zvlášť pro normální použití, navíc se obě liší pouze jedním atributem...to mohlo být trochu domyšleno Sad )
  • URL Rewriting
    • Použití http modulů, tento byl uveden jako příklad, vypadá dobře, zdarma a navíc je uvolněn i se zdrojovými kódy
  • Export do Wordu, Excelu a PowerPointu on-the-fly - zjištění, které moc nepřekvapilo je ale užitečné - nové formáty Open XML Officu 2007 jsou zip archivy, do kterých je možné jednodušše zasáhnout, stačí knihovna, která otevře zip soubory, dále je to už jen práce s xml soubory, .NET framework 3.0 bude práci s Open XML podporovat nativně, pokud chcete tuto vymoženost využívat už teď, můžete použít knihovnu SharpZipLib
Přednášku vřele doporučuji, vzhledem k velkému zájmu se bude opakovat, sledujte msdnku. Zároveň tímto děkuji Microsoftu za tyto přednášky a další akce, těším se na další...
Vlastnosti UserControlů

Nějaké články k tomuto tématu jsem hledal dlouho, bohužel přesnou odpověď jsem stále nedostavál. Přítrž tomu částečně učinil článek Roberta Sedera, se kterým jsem po e-mailu přišel i na ten poslední krok. Tak tedy od začátku. Tento způsob deklarace vlastnosti je ten známý:

public string
ParameterName
{
    set { Variable = value; }
    get { return Variable; }
}
 

 ITemplate

Tímto způsobem je možné od uživatele převzít klasickou kolekci controlů např. jako u prvku Panel, nebo vlastnostmi typu Template dalších prvků.

[PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(TemplateControl))]
public ITemplate ParameterName
{
    set { Variable = value; }
    get { return Variable; }
}



    Proměnná Variable musí být přirozeně typu ITemplate, jehož obsah pomocí metody Variable.InstantiateIn(PlaceHolder) vložíte do předem vytvořeného placeholderu. Užitečné třeba když budete vytvářet vlastní LoginControl - dva Templaty, jeden pro přihlášeného uživatele a druhý pro nepřihlášeného...Ještě poznámka, před definici třídy je potřeba vložit: [ParseChildren(true)]

Vlastní kolekce 

Další situace je vyžádání kolekce proměnných určitých typů, např. při vytváření nějakého typu Menu, kdy potřebujete získat kolekci položek, příklad ilustruji právě na této situaci.

Deklarace třídy položky menu:

public class MenuItem
{
    string _NavigateUrl, _Text;
    public string NavigateUrl
    {
       set { _NavigateUrl = value; }
       get { return _NavigateUrl; }
    }
    public string Text
    {
       set { _Text = value; }
       get { return _Text; }
    }
}


a teď jak zapsat parametr do samotného controlu

[PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(TemplateControl))]
public List<MenuItem> Items
{
    set { Variable = value; }
    get { return Variable; }
}


    Proměnná variable musí být typu List<MenuItem>, typ List<> je obsažen v namespacu System.Collections.Generic, je tedy nutné ho importovat nebo doplnit předponu. Zápis kolekce v kontrolu pak vypadá takto:

<prefix:NazevControlu runat="server" ID="NazevControlu1">
    <Items>
       <prefix:MenuItem NavigateUrl="http://www.interval.cz" Text="Interval" />
      <prefix:MenuItem NavigateUrl="http://www.aspnet.cz" Text="Aspnet.cz" />
   </Items>
</prefix:NazevControlu>

Napadá Vás ještě něco?
Numeric controls - díl 2 - NumericUpDown, NumericValidator

NumericValidator

I při použití sebelepšího zabezpečení pomocí klientských scriptů je vždy možnost, že je má uživatel vypnuté, je tedy nutná i obrana na serveru, nejjednodušší cestou je vytvoření validátoru. Pro větší univerzálnost stejně ale javascript přidám:

function ValidateNumbers(sender, args)
{
if(!isNaN(parseFloat(args.Value)))
{
var res = true;
for(i = 0; i < args.Value.length; i++)
{
if(isNaN(parseInt(args.Value.substr(i,1))))
{
//do podmínky níže můžete umístit tečku místo čárky
if(args.Value.substr(i,1) != ",")
res = false;
}
}
args.IsValid = res;
}
else
args.IsValid = false;
}

Dále je nutné zajistit validaci na straně serveru:

protected override void OnInit(EventArgs e)
{
base.OnInit(e);
base.EnableClientScript = true;
base.Page.RegisterClientScriptBlock("ValidateNumbers", "Sem umístěte script");
base.ClientValidationFunction = "ValidateNumbers";
base.ServerValidate += new ServerValidateEventHandler(ValidateNumbersServer);
}

protected void ValidateNumbersServer(object sender, ServerValidateEventArgs args)
{
double output;
if (double.TryParse(args.Value, System.Globalization.NumberStyles.Any, null, out output))

args.IsValid = true;
else
args.IsValid = false;
}

NumericUpDown

Posledním prvkem pro zadávání číselných dat je NumericUpDown, inspiraci jsem čerpal z Atlasu.

/* Tato funkce přebírá parametry: dir (=direction – směr, tedy zda se bude přičítat nebo odečítat), id textboxu, na který operace směřuje, step – krok, o kolik se hodnota zmenší/zvětší, maximum a minumum. Nejdříve se ověří, zda je minimum/maximum zadáno (pokud není server doplní za hodnotu 'NaN' a max ani min nebude brát v potaz), poté se přičte nebo odečte. Funkce replace je zde kvůli desetinnému oddělovači, protože JavaScript používá tečku, pokud ji používáte také, můžete v obou případech použití funkci smazat Nakonec se předá focus textboxu, aby uživatel mohl používat šipky (focus by se při každém stisku tlačítka přenášel na samotné tlačítko, což není žádoucí */ function NumericUpDown(dir, id, step, min, max)
{
var cont = true;
var num = document.getElementById(id).value.replace(",",".");
if(!isNaN(max))
{
if(dir == 1 && num == max)
cont = false;
}
if(!isNaN(min))
{
if(dir == 0 && num == min)
cont = false;
}
if(cont) {
if(dir == 1)
document.getElementById(id).value = parseFloat(num) + parseFloat(step);
else
document.getElementById(id).value = parseFloat(num) - parseFloat(step);
document.getElementById(id).value = document.getElementById(id).value.replace(".",",");
document.getElementById(id).focus();
}
}

/* Tato fce reaguje na klávesy stisknuté nad textboxem, přesněji na šipku nahoru a dolů, zavolá funkci NumericUpDown odpovídajícím způsobem */
function NumericUpDownKey(txt, e, step, min, max)
{
var uni = e.keyCode? e.keyCode : e.charCode;
if(uni == 38)
NumericUpDown(1, txt.id, step, min, max);
else
{
if(uni == 40)
NumericUpDown(0, txt.id, step, min, max);
}
}

Nyní na server:

Vytvořte prázdnou třídu, použil jsem dědičnosti z prvku Panel, nicméně můžete použít jakýkoli podobný prvek. Na událost OnInit vytvoříme textbox a dva buttony, které pomocí CSS napozicujeme a přiřadíme jim na událost onClick zavolání funkce NumericUpDown, detailněji v příloze.

Pozn. při doplňování javascriptů nezapomeňte, že se jedná o text, takže všechny znaky jako uvozovky atp. musíte opatřit lomítkem. Pokud chcete mít v javascriptu vypisovaném serverem pořádek, použijte znaky \n. Dále je nutno scripty uzavřít HTML značkami <script type="text/javascript">...</script>.

Numeric controls - díl 1 - Numeric TextBox

Omlovám se, že jsem již dost dlouhou dobu neaktualizoval blog, práce je moc, ale nějaký čas se přece jen našel, takže jsem vytvořil tři komponenty pro vkladání čísel do aplikace, hlavním důvodem výroby těchto controlů je obrana proti blbosti uživatelů...doufám, že vám pomohou

Úkolem tohoto prvku je možnost zapsání čísla, tím pádem zamezení zapsání písmen a dalších znaků, na druhou stranu je potřeba povolit znaménko mínus a desetinný oddělovač, každý se smí samozřejmě v hodnotě vyskytovat pouze jednou. K této kontrole použijeme, jak jinak, javascript.

/*
Popis funkce:
Tato fce je zavolána po každém stisku klávesy (událost onKeyUp), prohledá pole povolených znaků pomocí funkce IsAllowed (níže) a v případě, že znak (jeho Unicode kód) v poli není, vrátí hodnotu false a znak se do textboxu nezapíše.
*/

function CatchNonNumbers(e)
{
var DecUni = 44;
var uni = e.keyCode? e.keyCode : e.charCode;
var evt = window.event? event : e;
if(evt.ctrlKey || evt.altKey || evt.shiftKey)
return true;
else
{
if(uni == DecUni)
return true;
else
{
if(IsAllowed(uni))
return true;
else
return false;
}
}
}

/*
Tato zkontroluje celý řetězec opět po každém stisku klávesy, je to z důvodu obrany proti Ctrl + V – vložení hodnoty. Funkce prohledává řetezec znak po znaku, pokud nalezne číslo, desetinný oddělovač nebo znaménko mínus (musí být na prvním místě řetězce) nechá jej, v opačném případě jej smaže.
*/

function CheckString(txtBox)
{
varDecimalChar = ",";
var res = "";
var teckycarky = 0;
var s = txtBox.value;
for(j = 0; j < s.length; j++)
{
if(j == 0 && s[j] == "-")
res += s[j];
else
{
if(!isNaN(parseInt(s[j])))
res += s[j];
else
{
if(s[j] == DecimalChar && teckycarky == 0)
{
res += s[j];
teckycarky++;
}
}
}
}
txtBox.value = res;
}


/* Vrací true/false, pokud je znak povolen (nalezen v poli), nebo ne */ function IsAllowed(s)
{
var arr = new Array(8, 9, 13, 17, 35, 36, 37, 45, 38, 39, 40, 44, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57);
var found = false;
for(j = 0; j < arr.length; j++)
{
if(arr[j] == s) found = true; }
return found;
}

Pokud byste chtěli použít jako oddělovač desetinných míst tečku, je třeba přidat její Unicode kód do pole ve funkci IsAllowed (46, nezapomeňte smazát kód pro čárku - 44) a ve funkci CheckString na prvním řádku přiřadit proměnné DecimalChar hodnotu "." .

Teď vše uklídíme a vytvoříme ASP.NET Control. Vytvořte si prázdnou třídu, která bude dědit z klasického textboxu (System.Web.UI.WebControls.TextBox). Třída bude obsahovat pouze jednu funkci – override události OnInit, kde přidáme textboxu parametry, které zavolají odpovídající funkce. Javascript je napsán univerzálně, není tedy třeba ho vkládat pro každý prvek na stránce zvlášť, proto je vložení scriptu podmíněné.

protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if(!Page.IsClientScriptBlockRegistered("NumericTextBox"))
base.Page.RegisterClientScriptBlock("NumericTextBox",
"Sem umístěte JavaScript");

base.Attributes.Add("onkeypress",
"return CatchNonNumbers(event);");

base.Attributes.Add("onkeyup","CheckString(this);");
}

Pokud byste nalezli nějaký lepší postup, nebo připomínku, zkuste komentáře pod příspěvkem nebo mail asp.net@seznam.cz

P.S. zítra a pozítří přibudou další dva controly ze série Numeric Controls

Webground controls (aktualizováno)

    Počínaje včerejškem jsem začal tvořit další UserControly jako byl již uvedený TextBoxWaterMark, které budou ve formě dll knihovny volně ke stažení, prozatím jsou vytvořeny a čekají na otestování tyto controly:

- TextBoxWaterMark

- Numeric TextBox (je odchytáno i znaménko oddělovače desetinných míst, které se může vyskytovat jen jednou a podařilo se mi odchytit i událost při vložení  textu ze schránky pomocí Ctrl + V)

- NumericValidator - souvisí s předchozím, serverová kontrola, pro případ, že by uživatel měl vypnutý javascript

- NumericUpDown - další kontrol, který je součástí Microsoft AJAX control toolkit, mě narozdíl od toho Microsoftího funguje ovládání kurozorovými klávesami v Mozille :)

- Suggests (Radio, Checkbox) - po focusu TextBoxu se objeví seznam možných hodnot (RadioButtonList nebo CheckBoxList), možno zvolit, zda bude možné zadávat jen hodnoty ze seznamu nebo přidat i nové 

- HumanControl - klasická obrana proti robotům - vygeneruje obrázek s náhodným textem (můžete vygenerovat sami, nebo ho control vygeneruje sám) 

- HumanControlValidator - upravený custom validator, zadáte jen ID HumanControlu a odpovídajícího TexBoxu, zbytek se již vykoná automaticky

 - DeleteColumn - prvek pro GridView - vytvoří tlačítko na smazání, které se nejdříve zeptá na potvrzení pomocí javascriptového confirmu

- DatePicker - jednoduchý nástroj na výběr data, nezabírá místo na stránce, po kliknuté na obrázek se zobrazí kalendář, po vybrání data zmizí

Máte nápady na další Controly? Ozvěte se ve fóru, budu rád za jakýkoli feedback, zvláště upozornění na chyby, knihovna bude dostupná nejpozději do poloviny týdne.

Umístění vlastních controlů do aplikace

Pokud máte control napsaný jako třídu (tímto způsobem je napsán např. TextBox s nápovědou) umístíte jej do stránky následovně:

<%@ Register namespace="doplnte_namespace" tagPrefix="doplnte_predponu" %> 

Tento řádek přidejte do horní části stránky - pod direktivu <%@ Page %>, v případě, že používáte control v projektu často, je výhodnější jej zaregistrovat v souboru Web.config, takto

...
<system.web> 
    <pages>
        <controls>
            <add namespace="doplnte_namespace" tagPrefix="doplnte_predponu" />
        </controls>
    </pages>
</system.web>
...

control pak umístíte do stránky takto

<predpona:nazevTridy runat="server" .....></predpona:nazevTridy> 

v případě, že jste prvek vytvořili jako WebUserControl - soubor s příponou ascx, je postup podobný, nepoužijete atribut namespace ale src, kam jako hodnotu zadáte cestu k ascx souboru, dále je nutné kromě tagPrefix uvést ještě parametr tagName="nazev_controlu" 

TextBox s nápovědou jako ASP.NET control
   

    Microsoft ve zahrnul do svého frameworku Atlas (dnes ASP.NET Ajax) vcelku zajímavý prvek - TextBox s nápovědou (ukázka). Připadá mi ale zbytečné zahrnovat do projektu celý atlas framework a nutit uživatele stahovat 350 KB JavaScriptu, když vám výroba tohoto prvku zabere pouze pár minut nebo ne?

    Control jsem vyrobil jako třídu, která podědí vlastnosti z klasického textboxu (System.Web.UI.WebControls.TextBox). Přidal jsem následující parametry - HelpText (text, který se zobrazí jako nápověda), dále EmptyClass a FullClass - názvy CSS tříd, všechny parametry jsou typu string.



protected override void OnInit(EventArgs e)
{
  if (HelpText_ != null && EmptyClass_ != null && FullClass_ != null)
  {
    base.OnInit(e);
    base.CssClass = EmptyClass_;
    base.Attributes.Add("value", HelpText_);
    base.Attributes.Add("onfocus", string.Format("Activate('{0}');", base.ClientID));
    base.Attributes.Add("onblur", string.Format("Deactivate('{0}');", base.ClientID));
    Page.RegisterClientScriptBlock("TextBoxWithHelp", "<script type="\"text/javascript\"">\nfunction Activate(id) \n { \n var txt = document.getElementById(id); \n var HelpText = \"" + HelpText_ + "\"; \n if(txt.value == HelpText) \n { \n txt.className = \"" + FullClass_ + "\"; \n txt.value = \"\"; \n } \n } \n\n function Deactivate(id) \n { \n var txt = document.getElementById(id); \n var HelpText = \"" + HelpText_ + "\"; \n if(txt.value == \"\" || txt.value == HelpText) \n { \n txt.className = \"" + EmptyClass_ + "\"; \n txt.value = HelpText; \n } \n } </script>");
  }
  else
  {
    throw(new Exception("Vyplňte všechny parametry UserControlu!"));
  }
}


Při události OnInit se tedy provedou i tyto příkazy: nastavení CSS třídy (třídy za situace, kdy je zobrazen pomocný text), nastavi se atributy (ty se po renderování prvku prevedou do HTML - těmi se zavolá javascript), JScripty jsou do stránky přidávány pomocí funkce Page.RegisterClientScriptBlock, \n znaky ve stringu, který obsahuje řetězec jsou jen z estetických důvodů, nejsou nutné. Dále je ještě nutné udělat úpravu v předávání vlastnosti text, aby se v situaci, když uživatel odešlě pole tak, jak je na server pomocný text přepsal na prázdnou hodnotu, popř. bude nutné vytvořit vlastní validátor, jehož klientská část rozpozná pomocný text jako nevyplněné pole (doplním).

Ukázka TextBoxu (Celý zdrojový kód ke stažení)

Vyvojar.cz na prodej!