24/01/2009

Przerażająca 25

Home

Na stronie CWE pojawiła się bardzo świeże opracowanie opisujące 25 najniebezpieczniejszych i najczęściej spotykanych błędów programistycznych (po szczegóły zapraszam tutaj). Najniebezpieczniejszych w tym sensie, że zwiększających podatność oprogramowanie na wszelkiego rodzaju ataki. Zestawienie zostało stworzone przy współpracy kilkudziesięciu firm z Europy i Stanów Zjednoczonych. Na stronie znajdziemy również opis kilkuset innych błędów wraz dokładnym wyjaśnieniem i wskazówkami jak ich unikać. Naprawdę polecam. Martwi to, że spora część z wymienionych błędów jest dobrze znana od bardzo, bardzo dawna, a więc wydawałoby się, że programiści powinni być świadomi tych zagrożeń. Niektóre z błędów to wręcz przykłady akademickie: brak walidacji danych wejściowych, wstrzykiwanie SQL'a!

18/01/2009

Konsole są fajne :)

Home

Jeszcze jakiś czas temu w ogólnie nie myślałem o kupnie konsoli. Do czasu. Wczoraj zdarzyło mi się zagrać w kilka tytułów na Playstation 3. Szczególnie dobrze bawiłem się w Guita Hero. Dla niewtajemniczonych, to gra rytmiczna, w której można wcielić się w rockmana. Do gry potrzebna jest kontroler w postaci gitary, na którym w odpowiednich momentach trzeba naciskać przyciski i szarpać strony, a dokładniej coś co symuluje strunę :). Naprawdę trudno to opisać ale zabawa jest przednia. Jeszcze lepszy od gitary jest kontroler w postaci perkusji. To jest dopiero frajda. Dwie pałeczki w dłoni i walisz ile sił wlezie. Tak na marginesie seria gier Guitar Hero zarobiła ponad miliardów dolarów. Na blaszakach takich gier po prostu nie ma. W konsoli spodobało mi się jeszcze to, że wystarczy włożyć płytkę z grą napędu i można zacząć grać. Wszystko wczytuje się w maksymalnie kilkanaście sekund. I jeszcze jedna fajna rzecz. Jest dużo gier, w których można grać w dwie osoby. Na przykład w LittleBigPlanet chodzi o to aby z jednej strony zdobyć więcej punktów niż przeciwnik ale równocześnie trzeba z nim współpracować aby ukończyć planszę z powodzeniem. Jak dla mnie pomysł jest super. Zresztą wybór tytułów jest ogromny, szkoda tylko, że średnia cena to około 200 zł. Z drugiej strony konsolę kupujesz raz na kilka lat. Takie Playstation 2 jest na rynku chyba z 10. Teraz muszę się tylko zdecydować na Playstation 3 lub Xbox'a.

12/01/2009

Czemu zdarzenia nie działają ??? (część 2)

Home

W poście Czemu zdarzenia nie działają??? opisałem błąd, który doprowadza do sytuacji, w której nie otrzymujemy zdarzeń od dynamicznie tworzonych kontrolek. Jego rozwiązanie nie jest specjalnie skomplikowane i dla przypomnienia przytoczę je tutaj:

W przypadku dynamicznego tworzenia kontrolek, czy to bezpośrednio czy to przy okazji użycia kontrolek data bound zawsze należy pamiętać aby dynamiczne kontrolki były tworzone nie tylko przy inicjalnym odwołaniu do strony ale również przy kolejnych.

W tym poście chciałbym jeszcze zwrócić uwagę gdzie powinny być tworzone dynamiczne kontrolki. Najlepszym miejsce jest zdarzenie PreInit strony. Powodów jest kilka, a najważniejsze to:
  • Zdarzenie PreInit jest odpalane najwcześniej w cyklu życia strony. Jeśli stworzymy kontrolki w tym miejscu będą one dostępne w każdym kolejnym zdarzeniu - kontrolki dynamiczne będą zachowywały się tak samo jak kontrolki statycznie osadzone na stronie. To jest pierwszy i najważniejszy powód, a wszystkie wymienione dalej stanowią jego rozwinięcie.
  • Zdarzenie PreInit to jedyne miejsce, w którym możemy dynamicznie ustawić właściwość Theme. Jeśli stworzymy nasze kontrolki później to wartość tej właściwości nie będzie miała wpływu na sposób ich prezentacji.
  • Będziemy mieli zagwarantowane, że właściwości kontrolek zostaną odtworzone na podstawie ViewState.
  • Będziemy mieli pewność, że jeżeli dla dynamicznie stworzonej kontrolki ma zostać wygenerowane zdarzenie to zostanie. Innymi słowy będziemy mieli pewność, że w punkcie, w którym maszyneria ASP.NET określa dla jakiej kontrolki wywołać jakie zdarzenie, ta kontrolka będzie istnieć.
  • Takie są zalecenia :)

06/01/2009

ASP.NET Caching

Home

W poście tym chciałbym napisać kilka słów o unieważnianiu zawartości cache'a w aplikacjach ASP.NET na podstawie aktualizacji danych przechowywanych w bazie danych. Post ten nie jest jednak przewodnikiem na temat cache'owania w aplikacjach ASP.NET, opisuję w nim kilka moim zdaniem ważnych elementów. Post ten można traktować jako punkt wyjścia do dalszej nauki.

Idea jest bardzo prosta. W celu przyspieszenia aplikacji umieszczamy w cache'u jakieś dane np.: wynik zapytania czy też wyrenderowaną stronę (przy pomocy dyrektywy @OutputCache). Chcielibyśmy jednak aby w przypadku jeśli dane, na podstawie których zostało wykonane zapytanie, ulegną zmianie, ponownie wykonać zapytanie zamiast wczytywać jego wynik z cache'a. W aplikacjach ASP.NET możemy wybierać z dwóch możliwości. Jedna to obiekt klasy Cache dostępny przez właściwość strony o takiej samej nazwie. Dane umieszczone w tym pojemniku mogą zostać usunięte po upływie określonego czasu, kiedy zmianie uległ wskazy plik czy też (co interesuje nas w tej chwili) kiedy dane w bazie danych zostały zmienione. Po drugie mamy dostęp do cache'a przechowującego wyrenderowane strony czy też ich fragmenty. Z tego cache'a nie korzystamy bezpośrednio ale przy pomocy dyrektywy @OutputCache. W tym przypadku również możemy wybierać pomiędzy kilkoma wariantami unieważniania zawartości cache'a.

Przejdźmy do konkretów. W obu przypadkach aby powiązać dane w cache'u z danymi w bazie danych używamy klasy SqlCacheDependency. W przypadku cache'a dostępnego z poziomu strony musimy jawnie utworzyć instancję tej klasy. Przykład użycia znajdziemy tutaj. Natomiast w przypadku dyrektywy @OutputCache musimy użyć atrybutu SqlDependency.

Istotne jest co dzieje się pod spodem. SqlCacheDependency używa klasy SqlDependency (nazwa klasy jest taka sama jak nazwa wspomnianego wcześniej atrybutu). SqlDependency to z kolei wysoko poziomowa nakładka na inną klasę SqlNotificationRequest. Ważne jest to, że SqlDependency i SqlNotificationRequest współpracują tylko z bazą danych Sql Server 2005 i nowszymi, które dostarczają usługi powiadomień na poziomie wierszy - query notifications. To znaczy, że możemy wskazać wierszy, w przypadku zmiany których dane z cache'a zostaną usunięte. W przypadku starszych baz danych (lub nowych jeśli nie odpowiada nam query notifications) SqlCacheDependency wykorzystuje mechanizm monitorowania całych tabel zamiast wskazanej grupy wierszy. Jest to ogólnie rozwiązanie mniej wydajne.

Jeszcze parę słów o @OutputCache. Jak napisałem wcześniej aby użyć unieważniania na podstawie bazy danych należy wysterować atrybut SqlDependency. Składnia tego atrybutu jest następująca:
<%@OutputCache
...
SqlDependency="database/table name pair | CommandNotification"
...
%>
W przypadku podania pary nazwa bazy danych i nazwa tabeli zostanie użyte monitorowanie na poziomie całych tabel. W przypadku podania wartości CommandNotification zostanie użyte powiadamianie na poziomie wierszy, a dokładniej ASP.NET użyje wszystkich komend użytych w kontekście danej strony do utworzenia zależności pomiędzy danymi w cache'u, a danymi w bazie danych.

W tym momencie należy jeszcze zaznaczyć, że o ile klasa SqlCacheDependency jest właściwa dla aplikacji ASP.NET to SqlDependency i SqlNotificationRequest mogą być użyte również w innych przypadkach. W ogólności użycie SqlNotificationRequest jest raczej trudne i pracochłonne. W większości przypadków używa się SqlDependency. Przykład użycia tej klasy można znaleźć tutaj tutaj.

24/12/2008

Życzenia

Home

Życzę wszystkim aby spędzili Święta w taki sposób w jaki sobie wymarzą i z tymi ludźmi, przy których będą czuli się najlepiej.

Serdecznie pozdrawiam
Michał Komorowski