2010
04.24

Aplikacje dla Microsoft Mediaroom

Jak wyglądają aplikacje zaprojektowanie dla telewizji interaktywnych?
Można je zobaczyć między innymi tutaj.

2010
03.18

Na czym polega podpisywanie assembly?

Większość programistów podczas nauki programowania na platformie .NET omija temat silnych nazw i podpisywania assembly – nic dziwnego, kwestie te nie są najistotniejsze na etapie eksperymentowania z .NETem.
W komercyjnych, profesjonalnych albo bardziej zaawansowanych projektach kwestie te zyskują na znaczeniu. W tym wpisie zajmę się tematyką związaną z Global Assembly Cache, podpisywaniem podzespołów (polska nazwa assembly) i silnymi nazwami.

Po co podpisywać assembly?

Zasadnicza odpowiedź na to pytanie jest prosta: z tych samych powodów, dla których podpisuje się cokolwiek innego. Jeśli podpiszesz swoim kluczem prywatnym wiadomość email, odbiorca będzie mógł sprawdzić, że email rzeczywiście pochodzi od Ciebie; jeśli podpiszesz plik cyfrowo, będziesz mógł sprawdzić, czy nikt nie zmienił jego treści.

Między innymi z tych powodów stosuje się podpisywanie assembly – żeby potwierdzić tożsamość podzespołu.

Pełna tożsamość assembly składa się z 4 części:

  • krótkiej nazwy. Na platformie Windows jest to nazwa pliku bez rozszerzenia, np.:  Microsoft.DirectX.Direct3D;
  • kultury, czyli wersji lokalizacyjnej, np.: en;
  • tokena publicznego klucza podpisu: np.: 31bf3856ad364e35;
  • wersji np:  1.0.2902.0.

lub  w postaci jednego łańcucha:

Microsoft.DirectX.Direct3D, Culture=en, 
PublicKeyToken=31bf3856ad364e35, Version=1.0.2902.0

Dopóki nie podpiszesz swojego podezspołu, część PublicKeyToken pozostaje pusta.

Zmiana wartości jednej z tych 4 części skutkuje zmianą tożsamości biblioteki/assembly. Taki sposób identyfikacji bibliotek rozwiązał stary problem DLL Hell, który polegał na tym, że nowe instalacje nadpisywały starsze wersje jakiejś współdzielonej biblioteki, a wcześniej zainstalowane programy odwoływały się do tej nowej biblioteki próbując wykonać operacji, której implementacja się zmieniła w nowej wersji. Skutkował oto błędnym działaniem programów a czasami i systemu operacyjnego.

.NET Framework częściowo rozwiązuje ten problem za pomocą GAC (Global Assembly Cache), gdzie różne wersje tych samych współdzielonych bibliotek mogą być przechowywane bez przeszkód. Jak zatem .NE T rozróżnia rozmaite wersje bibilotek (np. DirectX for Managed Code)? Ano właśnie za pomocą tych 4-częściowych nazw.

Żeby jednak biblioteka (podzespół) mogła być umieszczona w GAC musi mieć silną nazwę.

Silna nazwa podzespołu – Assembly Strong Name

Silna nazwa (strong name) to owa 4-częściowa nazwa, która zawiera PublicKeyToken plus cyfrowy podpis. Jak powstaje ten podpis?

Żeby go utworzyć potrzeba pary kluczy (publiczny-prywatny) o długości 1024-bitów.  Klucz publiczny jest dołączany do 4-częściowej nazwy podzespołu właśnie jako PublicKeyToken. Taka komplementarna para jest wykorzystywana do szyfrowania za pomocą algorytmu RSA.

Kiedy kompilator jest proszony o cyfrowe podpisanie podzespołu, najpierw oblicza skrót z jego zawartości za pomocą funkcji haszującej. Później ten skrót jest szyfrowany kluczem prywatnym pochodzącym z pary kluczy i umieszczany w podzespole.

Tak powstaje podpisany podzespół z silną nazwą.

Kiedy później zachodzi potrzeba zweryfikować tożsamość danego podzespołu (mówiąc wprost: sprawdzić, czy nikt w nim nie grzebał), wykonywane są następujące kroki:

  • liczony jest skrót z zawartości podzespołu;
  • wyłuskiwany jest publiczny klucz (zapisany w podzespole);
  • klucz ten jest używany do rozszyfrowania skrótu podzespołu utworzonego podczas kompilacji;
  • oba skróty (ten z kompilacji i ten wyliczony w kroku pierwszym) są porównywane;
  • jeśli nie są równe znaczy to, że zawartość podzespołu została zmieniona.

Jak utworzyć silną nazwę i podpisać assembly?

Można to zrobić na kilka sposobów, np. za pomocą Visual Studio lub narzędzia linii komend sn.exe.
Omówię pierwszy sposób.
Wybieramy ustawienia naszego projektu (prawy przycisk na nazwie projektu -> Properties) i przechodzimy do zakładki Signing. Zaznaczamy opcję Sign the assembly.

Można to zrobić na kilka sposobów, np. za pomocą Visual Studio lub narzędzia linii komend sn.exe.

Omówię pierwszy sposób.

Wybieramy ustawienia naszego projektu (prawy przycisk na nazwie projektu > Properties) i przechodzimy do zakładki Signing. Zaznaczamy opcję Sign the assembly.

Podpisywanie podzespołu

Podpisywanie podzespołu

Możemy skorzystać z istniejącego pliku z kluczami, bądź utworzyć nowy. Stwórzmy nowy:

Podpisywanie podzespołu

Podpisywanie podzespołu - tworzenie klucza

Wpisujemy nazwę i hasło, które będzie chroniło nasze klucze przed niepowołanym dostępem.

Klikamy OK., zapisujemy projekt i kompilujemy. I już mamy podpisany podzespół z silną nazwą. Wygenerowany plik z kluczami zachowujemy do późniejszego użycia.

Jak zweryfikować, czy nasz podzespół ma poprawną tożsamość? Możemy użyć narzędzia sn.exe z opcją –v. Opcja –T wyświetla publiczny token.

Sprawdzanie podpisu

Sprawdzanie podpisu

Global Assembly Cache

Jak wspomniałem GAC – Global Assembly Cache (globalna pamięć podręczna podzespołów) jest miejscem składowania współdzielonych bibliotek DLL używany przez programy na platformie .NET. Dzięki GAC możemy przestać martwić się o fizyczne położenie używanych przez nas bibliotek na dysku. Jeśli podzespół został dodany do GAC, CLR zawsze będzie w stanie go znaleźć i załadować. GAC rozwiązuje też słynny problem DLL hell (”piekło DLL“) – umożliwia przechowywanie na jednej maszynie dowolnej liczby wersji danej biblioteki.

Standardowo GAC znajduje się w katalogu C:\Windows\Assembly\GAC.

Podzespoły znajdujące się w GAC są traktowane jako bezpieczne. Aby rzeczywiście tak było, podczas instalacji podzespołu w GAC przeprowadzana jest weryfikacja jego cyfrowego podpisu. A więc w GACu mogą być umieszczone tylko podzespoły z silną nazwą.

Poza tym tylko użytkownicy z grup administratorzy i użytkownicy zaawansowani mogą dodawać podzespoły do GAC.

Dla każdego nowododanego podzespołu tworzony jest katalog o nazwie tożsamej z krótką nazwą podzespołu (np. Microsoft.DirectX.Direct3D) a w nim podkatalogi odpowiadające wersjom – nazwy są tworzone wg wzorca wersja__publiczny token (np. 1.0.2902.0__31bf3856ad364e35).

Jak dodawać swoje podzespołu do GAC? Służy do tego narzędzie GACUTIL.EXE (parametry /i i /il instalują podzespoły; parametry /u i /ul odinstalowują podzespoły)

Jak bardzo jest to bezpieczne?

Krótko mówiąc: nie bardzo. Zmiana zawartości podpisanego assembly nie uniemożliwia jego uruchomienia przez CLR. Można co prawda zweryfikować integralność pliku, ale nie można uniemożliwić jego uruchomienia, zwłaszcza na poziomie pełnego zaufania.

Jeśli chodzi o GAC to integralność podzespołu jest sprawdzana wyłącznie w momencie dodawania go do GACa. Później już nie jest. Osoba z uprawnieniami administratora może więc podmienić zweryfikowany podzespół na niezweryfikowany.

Co więcej, silną nazwę można usunąć lub zamienić, co zostało opisane w tym artykule.

Jak więc zabezpieczyć swój kod, tak żeby nie można było go uruchomić, gdy jego integralność została naruszona? Zajmę się tym w jednym z kolejnych wpisów.

2009
12.16

Ogólnie o 70-562

Celem egzaminu numer 70-562 jest potwierdzenie kompetencji w zakresie programowania aplikacji internetowych za pomocą ASP.NET na platformie .NET 3.5. Jak czytamy na stronie poświęconej egzaminowi profil idealnego kandydata do zdania tego egzaminu to osoba pracująca w średnich-dużych zespołach z dwu-, trzyletnim doświadczeniem w dziedzinie tworzenia aplikacji webowych.

Prócz tego egzamin obejmuje wszystkie zagadnienia dotykające tematyki webaplikacji, między innymi:

  • Dostęp do danych za pomocą ADO.NET
  • Webserwisy
  • WCF
  • AJAX i Javascript
  • Konfiguracja IIS.

Zakres jest dość rozległy, ale nadal obraca się wokół pisania aplikacji internetowych i w tym kontekście sprawdza wiedzę z dodatkowych dziedzin.

Oczywiście – tak jak w przypadku innych egzaminów – samo kilkuletnie doświadczenie programistyczne nie gwarantuje pozytywnego złożenia egzaminu. Potrzebne jest jeszcze solidne powtórzenie swojej wiedzy i nauczenie się pewnych rzeczy na pamięć (co w codziennej pracy z powodzeniem jest zastępowane choćby przez Intellisense). Jak zatem dobrze przygotować się do złożenia egzaminu?

70-562 – jak zdać?

Dobrą pomocą do powtórzenia materiału jest na przykład książka: MCTS Self-Paced Training Kit (Exam 70-562): Microsoft .NET Framework 3.5-ASP.NET Application Development. Rozdział po rozdziale omawia  poszczególne zagadnienia, szczególnie dużo miejsca poświęcając ADO.NET. Trzeba zaznaczyć, że nie jest to książka do nauki programowania w ASP.NET  – można ją raczej nazwać repetytorium. Na uwagę zasługują ramki „Exam tip” z sugestiami, na co szczególnie zwrócić uwagę podczas egzaminu.

Książka na pierwszy rzut oka przeraża objętością – jest przynajmniej tak duża jak Self-Paced Training Kit dla egzaminu 70-536. Pamiętajmy jednak, że przykładowe kody źródłowe pisane są podwójnie (w C# i w VB.NET), a sporą cześć zajmują powtórki rozdziałów i przykładowe scenariusze.

Zasadniczo są dwa sposoby używania książki. Można próbować czytać ją tzw. ciurkiem i… po mniej więcej pół godziny odpłynąć do krainy Morfeusza. Nie polecam.

Drugi sposób – znacznie bardziej efektywny – to czytanie książki z otwartym Visual Studio i wypróbowywanie konstrukcji, o których właśnie czytasz. Oczywiście – pewnie większość z nich już kiedyś używałeś, ale być może nie zauważyłeś pewnych detali, które mogą zaważyć na tym, jak odpowiesz na pytania.

Olbrzymią wartością dodaną jest płyta z przykładowymi pytaniami testowymi. Jest 125 pytań podsumowujących poszczególne lekcje i 200 pytań praktycznych przypominających te, które będą na egzaminie.

W sieci można też kupić zestawy przykładowych pytań na MeasureUp lub na SelfTestSoftware, które także przypominają pytania na prawdziwym egzaminie i pozwalają ocenić stan przygotowania.

Tak na marginesie: w komentarzach do wpisu o egzaminie 70-536 użytkownik Matol napisał, że można kupić prawdziwe (lub zbliżone do prawdziwych) pytania z egzaminów albo nawet dostać je za darmo, w związku z czym – jego zdaniem – egzaminy te nie sprawdzają jakiejkolwiek rzeczywistej wiedzy. Z takim stwierdzeniem nie mogę się zgodzić (z wielu powodów). Jeśli natomiast Matol miał na myśli, że przez dumpy z pytań egzaminacyjnych wartość egzaminów się obniża, to owszem, skłonny jestem przyznać rację. Ale jednocześnie można powiedzieć, że również maturę i pracę magisterską można kupić (i także deprecjonuje to wartość tych egzaminów), a jednak nikt nie wyobraża sobie nie zrobić matury albo nie złożyć egzaminu magisterskiego. Tym niemniej Matol poczynił ciekawą uwagę i odniosę się do niej w innym wpisie.

Wracając do pytań testowych – oczywiście uczenie się odpowiedzi na pamięć nie ma najmniejszego sensu. Ale wykonywanie testów i sprawdzanie swoich odpowiedzi pozwala szybko zidentyfikować te obszary, w których nasza wiedza wymaga ulepszenia.

Ten model nauki sprawdził się w moim przypadku. Nie korzystałem z dumpów i nie mogę się pochwalić wynikiem 1000/1000, ale z powodzeniem zdałem egzamin. Oczywiście z powodu NDA nie mogę ujawniać treści egzaminu, ale zaskoczyła mnie minimalna liczba pytań dotycząca LINQ. Pozostałe proporcje były „w normie”.

Kilka podstawowych informacji dla osób, które jeszcze nie zdawały: egzamin pisze się w centrum szkoleniowym, które może organizować certyfikację Microsoft (aktualna lista ośrodków) za pomocą programu testującego na komputerze. Wynik zna się od razu po egzaminie. Do zaliczenia potrzeba 700 punktów na 1000 możliwych.

70-562 – zdałem i co dalej?

Jeśli planujesz przystąpić do egzaminu 70-562 raczej wątpię, że Twój wybór jest przypadkowy. Egzamin ten jest zwykle wybierany jako drugi, po zdaniu 70-536 (przeczytaj, jak przygotować się do egzaminu 70-536). Zdanie dwóch tych dwóch egzaminów skutkuje przyznaniem certyfikatu: Microsoft Certfified Technology Specialist  – .NET Framework 3.5, ASP.NET Application. Jeśli zdałeś te dwa egzaminy to jesteś wśród 59 osób w Polsce (dane na 8 grudnia 2009 – możesz zajrzeć do oficjalnej statystyki). Brzmi nieźle, prawda? ;)

Jeśli chcesz uzyskać wyższy poziom certyfikacji  – Microsoft Professional Developer (MPD) w dziedzinie ASP.NET na platformie .NET 3.5 i znaleźć się wśród 20 osób w Polsce posiadających ten certyfikat, będziesz zainteresowany zdaniem egzaminu 70-564: Pro: Designing and Developing ASP.NET Applications Using the Microsoft .NET Framework 3.5.

Podsumowanie

Na koniec krótkie podsumowanie:

  1. Egzamin 70-562 jest dla programistów ASP.NE T z kilkuletnim doświadczeniem.
  2. Istnieje sporo materiałów do nauki do egzaminu, w tym książka z MS-Press typu Self-Paced.
  3. Przydatne jest wykonywanie opisywanych ćwiczeń (pisanie kodu), tak żeby zaznajomić się z treścią w sposób praktyczny.
  4. Pomocne jest rozwiązywanie przykładowych testów i wyciąganie wniosków ze swoich błędnych odpowiedzi.
  5. Zdanie dwóch egzaminów 70-536 i 70-562 skutkuje uzyskaniem certyfikatu Microsoft Certified Specialist.

Powodzenia!

2009
11.30

W ASP.NET 2.0 wprowadzono interesującą i wydajną funkcjonalność – Web Parts. Czym są Web Parts? W skrócie: są to pewne zamknięte komponenty aplikacji internetowej, które są tworzone i zarządzane w jednolity sposób. Jedną z najbardziej użytecznych cech web partów (czasami będę odmieniać przez przypadki, ponieważ nie udało mi się znaleźć żadnego dobrego polskiego odpowiednika) jest to, że mogą być one dodawane, usuwane i edytowane nie tylko przez programistów, ale też przez użytkowników Twojej aplikacji internetowej. Web parts w akcji możesz zobaczyć np. na stronie: igoogle.com.

Ten wpis nie będzie o tworzeniu web partów – chcę skupić się na pewnym małym wycinku tematu – mianowicie na tworzeniu połączeń między web partami.

Po co łączyć web parts

Przypuśćmy, że tworzysz aplikację webową, która wyświetla szczegóły na temat europejskich miast. Chciałbyś zorganizować te stroną w taki sposób, żeby korzystała z web parts. W ten sposób umożliwiłbyś użytkownikowi samodzielne zarządzanie wyglądem strony. Załóżmy, że w jednym web parcie użytkownik będzie wpisywał (bądź wybierał z listy) nazwę miasta. W innych web partach pojawią się wówczas informacje takie jak:

  • liczba ludności miasta,
  • slideshow ze zdjęciami z miasta,
  • aktualna prognoza pogody, itd.

Aby uzyskać opisaną funkcjonalność, jako programista, musisz ustalić połączenie między web partami. Można to zrobić na dwa sposoby – 1) ustalić statyczne połączenie lub 2) umożliwić użytkownikom tworzenie dynamicznych powiązań. Omówię pierwszy z nich.

Statyczne powiązanie web partów

Statyczne powiązanie polega na wskazaniu jednego web parta jako dostawcy (provider) i jednego bądź więcej odbiorców (consumer).

Uwaga: dla ułatwienia jako web partów będziemy używać własnych kontrolek (user controls).

Stworzenie dostawcy polega na dodaniu do gotowej kontrolki metody, która będzie zwracała pewną wartość. W naszym przykładzie chcemy, aby była to nazwa miasta pochodząca z rozwijalnej listy. Oto, jak mógłby wyglądać przykładowy kod takiej kontrolki:

public partial class CityChooser : System.Web.UI.UserControl
{

    string _cityName = CityData.GetData().First().Name;

    [ConnectionProvider("My web parts connection", "GetCityName")]
    public string GetCityName()
    {
        return _cityName;
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (IsPostBack)
        {
            string userCity = DropDownList1.SelectedValue;
            _cityName = CityData.GetData().First(city => city.Name == userCity).Name;
        }

    }
}

Obiekt CityData zawiera po prostu listę miast w postaci struktur zawierających wszystkie potrzebne dane (np. pole Name czy Population). Dokładny wygląd tej klasy nie jest w tej chwili istotny. Najistotniejsza jest metoda:

[ConnectionProvider("My web parts connection")]
public string GetCityName()
{
    return _cityName;
}

Metoda ta (ważne – publiczna!) zwraca po prostu nazwę miasta wybranego z listy rozwijalnej. Atrybut ConnectionProvider określa, że jest to nasz dostawca danych dla innych web partów (konsumentów). Tu używamy z jednym parametrem (”przyjazną” nazwą połączenia), ale jest też przeciążona wersja z dwoma typu string. Wówczas pierwszy określa “przyjazną” nazwę naszego połączenia, a drugi definiuje unikalną nazwę naszego punktu połączenia. Można pominąć drugi parametr – wówczas nasz punkt będzie się nazywał default (oczywiście, gdybyśmy chcieli zdefiniować drugi ConnectionProvider, to wówczas trzeba już użyć drugiego parametru – nazwa default byłaby już zajęta).

Mamy zatem zdefiniowanego dostawcę naszych danych. Czas na konsumentów.

Stworzenie konsumenta polega na dodaniu do kontrolki będącej web partem metody (znów publicznej), która będzie przyjmować parametr – tego samego typu, jaki jest zwracany przez naszą metodę-dostawcę. Metodą tą należy opatrzyć atrybutem ConnectionConsumer. Całość mogłaby wyglądać następująco:

public partial class PopulationDisplayer : System.Web.UI.UserControl
{
    [ConnectionConsumer("My consumer")]
    public void ShowPopulation(string city)
    {
        lblCityPop.Text = CityData.GetData().First(c => c.Name == city).Population.ToString();
    }
}

I znów najważniejszy jest atrybut ConnectionConsumer. Parametry mają takie samo znaczenie jak w poprzednim przypadku.

Teraz, gdy mamy już zdefiniowanego dostawcę i co najmniej jednego odbiorcę, możemy ustalić połączenie. W tym celu musimy stworzyć stronę, na której będą działać nasze web party. Dodajemy oczywiście kontrolkę WebPartManager oraz WebPartZone, w której w ZoneTemplate umieszczamy nasze web party. Kod kontrolki WebPartZone może wyglądać następująco:

<asp:WebPartZone ID="WebPartZone3" runat="server" Style="width: 650px; height: auto;">
    <ZoneTemplate>
        <uc2:CityChooser ID="Provider" runat="server" />
        <uc3:PopulationDisplayer ID="Consumer" runat="server" />
    </ZoneTemplate>
</asp:WebPartZone>

Samo powiązanie definiujemy natomiast w kontrolce WebPartManager w części StaticConnections:

<asp:WebPartManager ID="WebPartManager1" runat="server">
    <StaticConnections>
        <asp:WebPartConnection
            ID="CityToPopulation"
            ProviderID="Provider"
            ConsumerID="Consumer">
        </asp:WebPartConnection>
    </StaticConnections>
</asp:WebPartManager>

I tak oto, gdy w jednym web parcie z listy wybierzemy miasto, to w drugim zobaczymy liczbę ludności tego miasta:

Powiązanie Web Parts

Powiązanie Web Parts

Gdybyśmy w atrybutach definiujących naszego dostawcę i konsumenta podali unikalne nazwy dla naszych punktów, np:

[ConnectionProvider("My web parts connection", "ProvideData")]
[ConnectionConsumer("My consumer", "ConsumeData")]

wówczas kod kontrolki WebPartManager wyglądałby nieco inaczej:

    <asp:WebPartManager ID="WebPartManager1" runat="server">
        <StaticConnections>
            <asp:WebPartConnection
            ID="CityToPopulation"
            ProviderID="Provider"
            ProviderConnectionPointID="ProvideData"
            ConsumerID="Consumer"
            ConsumerConnectionPointID="ConsumeData">
            </asp:WebPartConnection>
        </StaticConnections>
    </asp:WebPartManager>

Musielibyśmy wówczas określić, że chodzi nam o konkretne metody za pomocą właściwości: ProviderConnectionPointID i ConsumerConnectionPointID.

Gdybyśmy chcieli użyć większej ilości konsumentów, musielibyśmy zdefiniować odpowiednie WebPartConnection dla każdej pary web partów.

W taki sposób można łatwo definiować statyczne połączenia. O tym, jak umożliwić użytkownikom strony tworzenie dynamicznych połączeń, będzie następny (krótki) wpis.

Tym razem załączam kod źródłowy przykładowego rozwiązania – wersja dla Visual Studio 2008. Żeby korzystać z web partów, trzeba mieć SQL Server wersję Express, ponieważ web parts korzystają z bazy danych (App_Data/ASPNETDB.MDF), żeby zapamiętywać preferencje użytkownika. Paczka z kodem nie zawiera tego pliku – trzeba go sobie stworzyć samemu (np. przy pomocy narzędzia ASP.NET Configuration).

vssolutionWebParts static connections – kod C# (6,29 KB)

2009
05.05

W Internecie pojawił się film ze spotkania Steve’a Ballmera z polskimi społecznościami IT.

Polecam także stronę ze zdjęciami ze spotkania. Fotografie są wyświetlane za pomocą rewelacyjnego programu – Photosynth – opracowanego w Microsoft Live Labs.