Artykuł opublikowany na Codeguru.pl

Usługi WWW przebojem wkraczają w nasze życie. Coraz częściej istnieje potrzeba by korzystać z internetu nie tylko przy biurku w pracy czy domu, ale także poza nim. Dziś, w dobie urządzeń przenośnych, wystarczy schować do kieszeni np. Pocket-a i można pracować gdziekolwiek dusza zapragnie. Istnieje tylko jeden mały problem, a mianowicie aplikacja przeznaczona na komputer stacjonarny może „nie chcieć” pracować na urządzeniu mobilnym. Aby zapobiec tej sytuacji wystarczy stworzyć strony WWW w wersji mobilnej.

Do zobrazowania tego typu rozwiązania zostanie wykorzystana aplikacja, którą zaprezentowałem w artykule pt.: „Zabezpieczenie aplikacji ASP.NET przy użyciu mechanizmów bezpieczeństwa Forms”. W celu zaprezentowania kilku wybranych typów kontrolek wykorzystywanych podczas budowy aplikacji ASP.NET dla urządzeń mobilnych całe rozwiązane zostało wzbogacone o nową funkcjonalność polegającą na możliwości oceniania studenta przez nauczyciela – wykładowcę. Zakres działania aplikacji „Student” został pokazany na diagramie przypadków użycia (rys. 1).

clip_image002

Rys. 1 Funkcjonalność aplikacji Student – diagram przypadków użycia

W systemie mamy zdefiniowanych czterech aktorów: Pracownik, Administrator, Użytkownik i Wykładowca. Użytkownicy mają możliwość tylko zobaczenia danych o studentach. Pracownicy jak i Administratorzy po zalogowaniu mogą edytować dane studentów. Najwięcej uprawnień mają Administratorzy, którzy nie tylko mogą zastępować pozostałych aktorów, ale także mogą administrować systemem. Administrowanie systemem polega na dodawaniu nowych użytkowników i ich kasowaniu oraz daje możliwość przypisania użytkownikom funkcji. Nowym aktorem w tym zestawieniu jest Wykładowca, który może stawiać oceny studentom i poprawiać je. Ocenianie studentów przez Wykładowcę może się odbywać w dowolnym miejscu gdyż dodana funkcjonalność w postaci przypadku użycia „Oceń studenta” oraz przeglądanie danych o studentach zostały zaimplementowane zarówno jako aplikacja standardowa i jako aplikacja mobilna przeznaczona na PocketPC.

Struktura systemu

Zastosowanie trójwarstwowej struktury aplikacji umożliwia wykorzystanie wcześniej zbudowanych komponentów z warstw usług i danych. Dzięki temu zaimplementować dodatkowo trzeba tylko interfejs przeznaczony dla tej części systemu, która ma pracować na urządzeniach mobilnych. Na rysunku 2 przedstawiono diagram obrazujący rozmieszczenie, w kontekście warstw, klas realizujących przypadek użycia „Oceń studenta”.

clip_image004

Rys.2 Trójwarstwowa struktura rozmieszczenia klas w realizacji przypadku użycia „Oceń studenta” (Three Tier Diagram)

Jak widzimy na powyższym rysunku (rys.2) komunikacja pomiędzy bazą danych a interfejsem użytkownika odbywa się przy współudziale klasy OcenaCTR, która stanowi most łączący warstwę prezentacji z warstwą danych.

clip_image006

Rys. 3 Diagram wdrożenia aplikacji Student

Aplikacja mobilna, w zakresie omawianego przypadku użycia, korzysta z klas MobileWykladowca i MobileEdytujOcene a aplikacja standartowa z pozostałych. Biorąc także pod uwagę diagram wdrożenia (rys. 3) możemy zauważyć, że aby móc korzystać z tych samych zasobów należy wprowadzić mechanizm pozwalający na odróżnienie klienta mobilnego od klienta korzystającego z tradycyjnej przeglądarki internetowej. Ten mechanizm znajduję się w klasie Default znajdującej się w pliku Default.aspx.cs.

public class Default : System.Web.UI.Page {
       public Default() {
           Page.Init += new System.EventHandler(Page_Init);
       }
       private void Page_Load(object sender, System.EventArgs e) {
               // Sprawdzenie jakiego rodzaju urządzenie otwiera stronę
           if (Request.Browser["IsMobileDevice"] == "true" ) {
          //Przekierowanie na stronę przeznaczoną dla urządzeń mobilnych
               Response.Redirect("~/Mobile/MobileDefault.aspx");
                }
           else      {
// Przekierowanie na stronę dla standartowych urządzeń
               Response.Redirect("DesktopDefault.aspx");
           }
       }

Gdy korzystamy z PocketPC (gdy nie mamy urządzenia możemy skorzystać z emulatora, który jest dołączony do Visual Studio), zostaniemy przekierowani na stronę MobileDefault.aspx.  Na niej, w nagłówku znajdujemy baner, który jest na każdej stronie w systemie. Poniżej znajduje się tabelka z listą nazwisk studentów (rys. 4). Lista ta to nie jest DataGrid znany z Web Forms, ale ObjectList przeznaczony specjalnie do używania w aplikacjach mobilnych. Z racji tego, że ekran w PocketPC jest mały to widzimy tylko listę nazwisk, ale już kliknięcie w nazwisko pozwala nam zobaczyć wszystkie dane o wybranym studencie.

ObjectList

Zastosowanie kontrolki ObjectList nie jest skomplikowane. Po uruchomieniu formularza przeznaczonego dla aplikacji mobilnych należy przeciągnąć z paska narzędzi na formularz kontrolkę ObjectList i w kodzie programu dodać jej obsługę, która niczym się nie różni od obsługi DataGrid i wygląda następująco:

//Tworzenie egzemplarza dla klasy StudentCRT
               Student.StudentCTR dane = new Student.StudentCTR();
               //Załadawanie danych do kontrolki ObjectList
               Studenci.DataSource = dane.ZobaczStudentow();
               Studenci.DataBind();

Następnie klikamy prawym klawiszem na kontrolkę i wybieramy Property Builder, a potem otwieramy zakładkę Fields i tam dodajemy interesujące nas pola, które zostały wybrane za pomocą metody ZobaczStudentow.

Autoryzacja użytkowników i bezpieczeństwo aplikacji

W banerze po lewej stronie znajduje się link umożliwiający uruchomienie strony z formularzem do logowania. Po wpisaniu loginu i hasła uruchamia się zdarzenie Loguj, którego obsługa znajduję się poniżej:

private void Loguj(object sender, System.EventArgs e)
          {
               //sprawdzenie czy użytkownik istnieje w bazie danych
               UzytkownikCTR konto = new UzytkownikCTR();
String uzytkownikId = konto.Logowanie(login.Text, StudentOchrona.Szyfr(haslo.Text));
               if ((uzytkownikId != null) && (uzytkownikId != ""))
               {
     // autoryzacja użytkownika i powrót na stronę startową          
MobileFormsAuthentication.RedirectFromLoginPage(login.Text, true);
               }
               else
               {
                    wiadomosc.Visible=true;
                    wiadomosc.Text = "Sprawdź login lub hasło!";
               }

Po pomyślnym przejściu autoryzacji powracamy na stronę startową (rys. 4), na której poza nazwą użytkownika znajduje się kontrolka Command (odpowiednik LinkButton) o nazwie Wyloguj.

Każda strona, do której dostęp jest ograniczony co do wybranych typów użytkowników jest chroniona następującym kodem:

// Sprawdzenie czy użytkownik uruchamiajacy stronę jest Wykładowcą
          if (StudentOchrona.SprawdzenieFunkcji("Wykladowca") == false)
               {
          // przekierowanie na stronę z komunikatem o braku uprawnień          this.RedirectToMobilePage("~/Mobile/MobileBrakUprawnien.aspx");
               }

Gdy chcemy się wylogować to klikamy w wyżej wspomniany przycisk Wyloguj, który uruchamia zdarzenie Wyloguj_Click, które odpowiada za wylogowanie użytkownika. Implementacja wylogowania dla aplikacji mobilnej wygląda w następujący sposób:

private void Wyloguj_Click(object sender, System.EventArgs e)
          {
               Logowanie.Visible=true;
               Powitanie.Visible=false;
               Wyloguj.Visible=false;
               FormsAuthentication.SignOut();
               // utworzenie egzeplarza klasy MobilePage
               System.Web.UI.MobileControls.MobilePage strona =new System.Web.UI.MobileControls.MobilePage();          
          // przekierowanie na stronę startową     strona.RedirectToMobilePage("~/Mobile/MobileDefault.aspx");    

          }

clip_image008

Rys 4. Widok strony głównej aplikacji Student w wersji na PocketPC

Gdy zalogujemy się jako Wykładowca obok linku Start pokazuję się link Ocena. Aby jednak do tego doszło muszą być sprawdzone uprawnienia zalogowanego użytkownika i ma to miejsce podczas wykonywania poniższego kodu:

// Sprawdzenie czy nastapiła autoryzacja
               if (Request.IsAuthenticated == true)     
               {
                    String[] roles;
                    // Pobranie ról użytkownika
                    UzytkownikCTR user = new UzytkownikCTR();
                    roles = user.WezRole(Context.User.Identity.Name);
                    // stworzenie string, a w celu zapisania ról
                    String roleStr = "";
                    foreach (String role in roles)
                    {
                         roleStr += role;
                    }
                    if (roleStr == "Wykladowca")
                    {
                         Oceny.Visible=true;
                    }
               }

Link Ocena umożliwia uruchomienie formularza (plik MobileWykladowca.aspx), na którym będziemy mogli wyświetlić dane o ocenach studentów. Oceny studentów są wyświetlane po wybraniu nazwy przedmiotu za pomocą kontrolki SelectionList.

SelectionList

Kontrolka SelectionList jest mobilnym odpowiednikiem takich kontrolek standardowego ASP.NET jak DropDownList, CheckBox, MultiSelectionList, ListBox i Radio. Typ kontrolki ustawiamy parametrem SelectType znajdującym się we właściwościach kontrolki. W prezentowanej aplikacji parametr ten jest ustawiony na DropDown. Załadowanie danych do kontrolki odbywa się w sposób identyczny jak ma to miejsce przy obsłudze zwykłego DropDownList i wygląda następująco:

               Student.OcenaCTR przed = new Student.OcenaCTR();
               PrzedmiotList.DataSource = przed.WezPrzedmiot();     
               PrzedmiotList.DataTextField= "nazwaPrzedmiotu";
               PrzedmiotList.DataValueField="idPrzedmiotu";
               PrzedmiotList.DataBind();

Implementacja kontrolki wyboru w aplikacjach mobilnych nastręcza jeden problem a mianowicie SelectionList nie zawiera opcji AutoPostBack, która umożliwia wczytanie danych po wybraniu interesującej nas zmiennej. Problem ten można rozwiązać po przez umieszczenie dodatkowego przycisku „Pokaż listę”, który wczytuje wybraną wartość z SelectionList i jednocześnie uruchamia kontrolkę List odpowiedzialną za wyświetlenie ocen z wybranego przedmiotu. Wciśniecie przycisku „Pokaż listę” uruchamia zdarzenie Wybierz, którego obsługa wygląda następująco:

private void Wybierz(object sender, System.EventArgs e)
          {
               // wczytanie parametru z kontrolki SelectionList
IdPrzedmiotu=PrzedmiotList.SelectedIndex.ToString();
               // ***Wczytanie danych do kontrolki List***
               //Tworzenie egzemplarza dla klasy OcenyCRT
               Student.OcenaCTR oc = new Student.OcenaCTR();
               //Załadowanie danych do egzemplarza DataSet
               ds = oc.ZobaczOceny(Convert.ToInt32(IdPrzedmiotu));
               DataBind();
          }

List

Kontrolka List umożliwia wyświetlenie jednej zmiennej, dlatego też jej implementacja została wzbogacona o element DeviceSpecific, który daje możliwość zdefiniowania dodatkowych właściwości kontrolek w zależności od wybranego urządzenia. DeviceSpecific możemy stosować przy takich elementach jak Forms, Panel, List, ObjectList. Aby móc skorzystać z dobrodziejstw DeviceSpecific musimy najpierw dodać w pliku Web.config następujące linijki:

<deviceFilters>
     <filter name="isJScript" compare="javascript" argument="true" />
     <filter name="isPocketIE" compare="browser" argument="Pocket IE" />
     <filter name="isHTML32" compare="preferredRenderingType" argument="html32" />
      </deviceFilters>

W przedstawionym rozwiązaniu użyjemy DeviceSpecific do wyświetlenia więcej niż jednego pola oraz do wyświetlenia w każdej linii elementu typu link umożliwiający przejście do strony MobileEdytujOcene.aspx, na której możemy poznać szczegóły dotyczące oceny lub poprawić ocenę. Pełna specyfikacja kontrolki List, zapisana w HTML, znajduje się poniżej:

<!–Uruchomienie kontrolki List po przez wczytanie do Data Source DataSet zdefiniowanego jako zmienna ds –>
<mobile:List id=OcenyList runat="server" DataSource="<%# ds %>" DataTextField="idOceny">
     <DeviceSpecific>
          <Choice Filter="isJScript">
               <HeaderTemplate>
          <table width="95%" border="0" cellspacing="0" cellpadding="0">
               </HeaderTemplate>
                    <ItemTemplate>
                         <tr>
                         <td>
                         <font face="Verdana" size="-2">
                                   <a>
                         <!– Wczytanie pól zapisanych w DataSet –>
                                   <%# DataBinder.Eval(((MobileListItem)Container).DataItem, "nazwisko") +", wydział: "+ DataBinder.Eval(((MobileListItem)Container).DataItem, "wydzial") %>
                                   </a>
                                   </font>
                         </td>
                         <td align="right">
                                   <font face="Verdana" size="-2">
                    <!– Link uruchamiajacy stronę MobileEdytujOcene.aspx w raz z parametrami na której możemy zobaczyć
                    uszczegółowienie danych oraz poprawić ocenę–>
                                   <mobile:Link id="edytuj" text="zobacz ocenę" runat="server" NavigateUrl=´<% #"MobileEdytujOcene.aspx?idOceny="+DataBinder.Eval(((MobileListItem)Container).DataItem, "idOceny")+"&amp;nrAlbumu="+DataBinder.Eval(((MobileListItem)Container).DataItem, "nrAlbumu")%>´ >
                                   </mobile:Link>
                                   </font>
                                   </td>
                                   </tr>
                    </ItemTemplate>
                    <FooterTemplate>
                         </table>
                    </FooterTemplate>
          </Choice>
     </DeviceSpecific>
</mobile:List>

Gdy zostanie uruchomiony link do strony MobileEdytujOcene.aspx następuje przekierowanie, które zawiera poza wywołaniem strony także parametry dotyczące nrAlbumu i idOceny. Przekierowanie na tę stronę znajduje się także nad kontrolką wyboru przedmiotu i ma nazwę „Dodaj ocenę”, z tym, że to przekierowanie nie zawiera żadnych dodatkowych parametrów.

Strona MobileEdytujOcene.aspx wykorzystuje ciekawą właściwość stron przeznaczonych dla aplikacji mobilnych. Własność ta polega na tym, że w odróżnieniu od standartowych stron ASP.NET, gdzie jedna strona to jeden formularz i ze względu na małe wymiary ekranu, na stronach przeznaczonych dla aplikacji mobilnych możemy umieścić więcej niż jeden formularz. W przedstawionej aplikacji formularze mają nazwy „DodajForm” i „PoprawForm”. Uruchomieniem właściwego formularza zależy od tego czy wraz z uruchomieniem strony zostaną dostarczone wymagane zmienne. Kod obsługujący decyzję wyboru jest zaprezentowany poniżej:

// sprawdzenie czy podane są parametry
if ((Request.Params["idOceny"] != null)||(Request.Params["nrAlbumu"] != null))
               {
                    NrAlbumu=Int32.Parse(Request.Params["nrAlbumu"]);
                    IdOceny=Int32.Parse(Request.Params["idOceny"]);
               }
               if (Page.IsPostBack == false)
               {     
                    //Sprawdzenie czy jesy idOceny
                    if (Request.Params["idOceny"] != null)
                    {
     // uruchomienie formularza odpowiedzialnego za poprawianie danych
                         ActiveForm=PoprawForm;
               Student.StudentCTR dane = new Student.StudentCTR();
               //Wczytanie danych
          SqlDataReader dr = dane.ZobaczJednegoStudenta(NrAlbumu);
                         // czytanie pierwszego wiersza
                         dr.Read();
     // do każdego pola jest przypisywana wartość komórki z tabeli Student
                         NazwiskoP.Text = (String) dr["nazwisko"];
                         ImieP.Text = (String) dr["imie"];
                         WydzialP.Text = (String) dr["wydzial"];
                         // zamknięcie odczytu danych
                         dr.Close();
     //Przypisanie kontrolce wartości zmiennej NrAlbumu     
//jednocześnie nastepuje zapisanie tej zmiennej w postaci string
                         AlbumuLabel.Text =NrAlbumu.ToString();
                         // Tworzenie egzemplarza klasy OcenaCRT                    Student.OcenaCTR ocena = new Student.OcenaCTR();
                         //Wczytanie danych
               SqlDataReader oc = ocena.ZobaczWybranaOcena(IdOceny);
                         // czytanie pierwszego wiersza
                         oc.Read();
               // do każdego pola jest przypisywana wartość odpowiedniej
          PrzedmiotP.Text = (String) oc["nazwaPrzedmiotu"];
          OcenaP.Text = ((decimal) oc["ocena"]).ToString();
                    // zamknięcie odczytu danych
                    oc.Close();
                    }
                    else
                    {
// uruchominie formularza odpowiedzialnego za umożliwienie dadania oceny
                         ActiveForm=DodajForm;
                    }
               }

Powyższy fragment kodu pokazuje także sposób wczytania danych do takich elementów jak TextBox czy Label. Nie różni się on niczym od metody stosowanej przy wczytywaniu danych w aplikacjach przeznaczonych na komputery stacjonarne. Podobnie ma się rzecz z wpisywaniem danych do bazy danych. Metody odpowiadające za dodanie/poprawienie ocen są prawie identyczne w sposobie implementacji w obu rodzajach aplikacji. W aplikacji przeznaczonej dla PocketPC metoda odpowiadająca za dodanie oceny wygląda tak:

private void Dodaj_Click(object sender, System.EventArgs e)
          {
               //Wczytanie danych z kontrolek rozwijanych
               Album=StudentList.SelectedIndex.ToString();
               Przedmiot=PrzedmiotList.SelectedIndex.ToString();     
(…)
// Dodanie danych do tabeli Oceny po przez odwołanie się do metody DodajOcene
                         oce.DodajOcene(Convert.ToInt32(Album),IdOceny,Convert.ToInt32(Przedmiot),Convert.ToDecimal(OcenaPole.Text),Context.User.Identity.Name );
//powrót na stronę poprzednią  
          this.RedirectToMobilePage("~/Mobile/MobileWykladowca.aspx");
                    }

Natomiast metoda odpowiedzialna za poprawienie oceny jest zaimplementowana w następujący sposób:

public void Popraw(object sender, System.EventArgs e)
          {
                    // Tworzenie egzemplarza klasy OcenaCTR
                    Student.OcenaCTR ocena = new  Student.OcenaCTR();
                    // Poprawienie danych w tabeli Oceny
                    ocena.PoprawOcene(IdOceny,Convert.ToDecimal(OcenaP.Text),Context.User.Identity.Name );
          //powrót na stronę poprzednią  
          this.RedirectToMobilePage("~/Mobile/MobileWykladowca.aspx");
               }

Podsumowanie

Budowa aplikacji mobilnych wykorzystujących ASP.NET jest bardzo podobna do sposobu, w jaki tworzymy aplikacje przeznaczone dla komputerów stacjonarnych. W podobny sposób budujemy interfejs użytkownika. W podobny sposób implementujemy zabezpieczenia i wypełniamy kontrolki danymi. Czasami tylko musimy pamiętać o specyficznych własnościach urządzeń przenośnych takich jak np. wielkość ekranu czy charakterystyczne cechy niektórych kontrolek. Niewątpliwą zaletą zaproponowanego rozwiązania jest korzystanie przez aplikację standartową i mobilną z tych samych klas usług i tej samej bazy danych. Tanim kosztem, pozwala to na dostęp do tych samych usług WWW zarówno użytkownikowi, który zasiadł za biurkiem przed komputerem jak i użytkownikowi, który siedzi w parku z pocketem w dłoni.

Kod źródłowy aplikacji i backup bazy danych.

Technorati Tagi: ASP.NET,aplikacje webowe

1 Comment

  1. Krzysztof 'raczus' Raczek

    Fajny art. trochę starszy ale dobrze napisany. Fajnie się go czytało;-) Pozdrawiam

Zostaw odpowiedź

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

Możesz użyć tych HTML tagów i atrybutów: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Close