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).
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”.
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.
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");
}
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")+"&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.
Fajny art. trochę starszy ale dobrze napisany. Fajnie się go czytało;-) Pozdrawiam