Artykuły

A A A
Drukuj Ekportuj do PDF
Opublikowane: 2002.06.23 1:51 | Jacek Kolonko | Aktualizacja: 2006.01.23 20:27

Wykorzystanie SQLXML 3.0 oraz Visual Basic .NET do budowy stron intranetowych

tagi: Visual Basic
Przykładowa aplikacja jest narzędziem internetowym przeznaczonym do zarządzania projektami i zadaniami. Pomysł polegał na tym, by polepszyć produktywność zespołu przez wprowadzenie jego członków do zarządzania projektami i zadaniami. Celem tworzenia aplikacji było opracowanie prostego interfejsu internetowego, który pozwoli użytkownikom na sporządzanie i zmianę projektów i zadań oraz ustawienie interfejsu przez ustawienie różnych opcji sortowania i filtrowania.

Wsparcie dla Extensible Markup Language (XML) oraz właściwości XML zawartych w Microsoft® SQL Server™ 2000 pozwala programistom na budowę stron Web oraz zaawansowanych aplikacji baz danych, które funkcjonują na różnych platformach systemowych oraz językach programowania. Wsparcie dla XML i Microsoft .NET Framework w SQL Server od wersji SQL Server 2000 i dodanie do SOAP Web Services wsparcia dla SQL Server dalej rozwinęło te możliwości. Przykładowa aplikacja, opisana w tym dokumencie, demonstruje, jak można używać Microsoft SQLXML 3.0 i Microsoft Visual Basic® .NET do zbudowania rozszerzalnej i skalującej się strony Web.

Opis przykładowej aplikacji

Przykładowa aplikacja „Projekty i system śledzenia zadań” jest narzędziem internetowym przeznaczonym do zarządzania projektami i zadaniami. Pomysł polegał na tym, by polepszyć produktywność zespołu przez wprowadzenie jego członków do zarządzania projektami i zadaniami. Celem tworzenia aplikacji było opracowanie prostego interfejsu internetowego, który pozwoli użytkownikom na sporządzanie projektów i zadań, na zmianę projektów i zadań oraz ustawienie interfejsu przez ustawienie różnych opcji sortowania i filtrowania.

Dane o określonych projektach i zadaniach są zapisywane w bazie danych SQL Server 2000, która zawiera także informacje pracowników, dotyczące ustawień i opcji (sortowania i filtrowania) w projektach i zadaniach.

SQLXML 3.0 został użyty do stworzenia aplikacji przede wszystkim klas zarządzających (Managed Classes) SQLXML, diagramów aktualizujących (updategrams), plików z szablonami XML, wsparcia serwisów Web (SOAP). Pliki szablonów XML, które zawierają zapytania SELECT...FOR XML, są używane do pobierania danych. Pliki diagramów aktualizujących (updategrams) są używane do wykonywania wszystkich operacji modyfikacji bazy danych (insert i update). Klasy zarządzające SQLXML (SQLXML Managed Classes) służą do uruchamiania plików szablonów XML oraz diagramów aktualizujących.

Zanim zaczniemy ustawiać aplikację, należy przyjrzeć się strukturze bazy danych oraz przykładowym danym.

Struktura bazy danych

Baza danych Projects zawiera następujące tablice:

  • tblEmployees
  • tblEmpPreferences
  • tblProjects
  • tblDepartments
  • tblStatusCodes
  • tblPriorityCodes
  • tblTasks

Kolumny tych tablic przedstawione są na poniższym diagramie bazy danych:

Struktura bazy danych Projects
Rysunek 1. Struktura bazy danych Projects

Tabela tblEmployees zawiera informacje o pracownikach, tzn. trzy rekordy z informacjami o pracownikach, jak pokazano na poniższym przykładzie. Pole EmailAlias jest używane do logowania się do systemu.

Row_ID FirstName LastName EmailAlias DeptCode
1 Alan Steiners Alan 10
2 Kim Ralls Kim 1
3 Bradley Beck Bradley 1

Tabela tblEmpPreferences jest używana do przechowywania informacji o preferencjach w sortowaniu i filtrowaniu, wybranych przez pracowników. Użycie bazy danych po stronie serwera do przechowywania danych (w przeciwieństwie do plików cookie po stronie klienta) pozwala pracownikom na użycie dowolnego komputera przy takich samych ustawieniach, jakie wybrali wcześniej.

Tablice tblProjects i tblTasks mają prawie taką samą strukturę, zawierają też niezależnie od siebie informacje o projektach i zadaniach.

Tabela tblPriorityCodes zawiera kody priorytetów. Przykładowa baza danych definiuje trzy priorytety: średni (Medium), niski (Low) i wysoki (High).

Tabela tblDepartments zawiera nazwy różnych działów firmy.

W tabeli tblStatusCodes znajdują się informacje o statusie projektu lub zadania. Poszczególne kody statusu zawierają: nie rozpoczęte (Not Started), w trakcie (In Progress), zakończone (Completed), oczekujące (Waiting), w trakcie (Ongoing), osiągnięte (Achieved), wstrzymane (Deferred) i anulowane (Cancelled).

Dostęp użytkownika do przykładowej aplikacji

Kiedy pracownik po raz pierwszy odwiedza intranetową stronę Projekty (Projects), jest proszony o podanie firmowego adresu e-mail. W zależności od wprowadzonego adresu e-mail, preferencje użytkownika pobierane są z tabeli tblEmpPreferences i przekierowywane do okna Projekty (Projects) lub do okna Zadań (Tasks), stosownie do preferencji wyszczególnionych w ustawieniach pracownika. Plik cookie (zapisywany po stronie przeglądarki klienta) jest używany do określenia, czy pracownik odwiedza stronę po raz pierwszy, czy ponownie.

Pracownicy mogą przeglądać wszystkie projekty lub filtrować listę danych przez wybór wydziału, właściciela, statusu lub priorytetu albo przez połączenie tych pozycji. Okno Projektów pozwala pracownikom na wprowadzanie zmian do istniejących projektów, przeglądanie zadań dla projektów lub dodawanie nowych projektów. Okno Zadań pozwala pracownikom na przeglądanie wszystkich lub przefiltrowanych zadań, dodanie nowych zadań lub zmianę istniejących.

W tej aplikacji nie zostało zaimplementowane sprawdzanie bezpieczeństwa. Wszystkie dane są dostępne dla wszystkich.

Zakładka Opcje (Options) pozwala pracownikom na określenie sposobu, w jaki informacje mają być sortowane, określenie dodatkowych kryteriów filtrowania sortowania oraz na zalogowanie się do systemu jako inny użytkownik.

Zakładka Administrator (Admin) pozwala administratorowi na zarządzanie pracownikami, wydziałami, kodami statusu i kodami priorytetów.

Architektura przykładowej aplikacji

System zarządzania projektami i zadaniami składa się z trzech podstawowych komponentów:

  • SQL Server 2000, który zawiera bazę danych Projects.
  • Microsoft Internet Information Services (IIS 5), zawierający wirtualny katalog strony internetowej, który zawiera pliki źródłowe ASP.NET − napisane przy użyciu Visual Basic .NET. Serwer internetowy zawiera także wirtualny katalog SQLXML 3.0, który wskazuje na bazę danych Projects. Ten wirtualny katalog zawiera dwie wirtualne nazwy − Szablony (Templates) i SQLXMLWebSvc. Nazwa wirtualna Szablony (Templates) jest typu szablon (template) − zawiera pliki szablonów XML i pliki diagramów aktualizujących (updategram). Nazwa wirtualna SQLXMLWebSvc jest typu soap i jest używana do wywoływania metod usługi WWW, która z kolei wywołuje przechowywane procedury SQL serwera bazy danych SQL Server 2000.
  • Klient przeglądarki lub klient aplikacji Microsoft Visual Basic 6.0. Klient przeglądarki używa strony ASP.NET i wykonuje żądania dla stron WWW z rozszerzeniem.aspx. Aplikacja Visual Basic 6.0 jest klientem usługi WWW, która pozwala na przeglądanie statystyk projektów i zadań. Ta aplikacja używa Microsoft SOAP Toolkit 2.0 do tworzenia zapytań SOAP, a Microsoft XML Core Services (MSXML 4.0) do przetwarzania odpowiedzi.
Architektura przykładowej aplikacji
Rysunek 2. Architektura przykładowej aplikacji

Strony WWW (pliki .aspx) używają klas zawartych w Components.dll do tworzenia zapytań do bazy danych i innych zadań, takich jak: zastosowanie arkuszy XSLT (Extended Stylesheet Language Tranformations) i wyznaczanie wyrażeń języka XPath.

Components.dll zawiera jedną klasę dla każdej tabeli w bazie danych. Wszystkie te klasy używają klasy DBAccess, która zawiera ogólne metody dla wywoływania i przetwarzania plików szablonów SQLXML. Klasa narzędziowa wewnątrz Components.dll udostępnia metody pozwalające na zastosowanie arkuszy stylów, wykonywanie wyrażeń XPath itp.

Klasa DBAccess wewnątrz Components.dll używa klas zarządzających SQLXML 3.0 do wykonywania plików szablonów XML i diagramów aktualizacji. Pozwala też na uruchomienie szablonu ciągu znaków i szablonu pliku.

Klient aplikacji Visual Basic jest klientem usługi WWW używającej SOAP i wysyła żądania SOAP bezpośrednio do wirtualnej nazwy SQLXML 3.0. (sposób skonfigurowania wirtualnej nazwy SQOP, by wskazywała na przechowywane procedury w serwerze SQL Server 2000, przedstawiono w następnej części artykułu). W tej aplikacji znajdują się dwie przechowywane procedury: jedna, która zwraca statystykę projektów, druga zwracająca statystykę zadań. Obydwie te procedury są metodami serwisów WWW, które są udostępnione przez skonfigurowanie wirtualnej nazwy SOAP. Aplikacja kliencka Visual Basic wywołuje te metody serwisu WWW, następnie analizuje odpowiedź i wyświetla wyniki.

Wymagania dla budowy i testowania przykładowej aplikacji

By zbudować i testować intranetową stronę WWW, potrzebne są następujące narzędzia:

  • Microsoft Windows® 2000 lub Windows XP
  • Microsoft Internet Information Services 5.0 (IIS 5), lub nowszy
  • Microsoft SQL Server 2000 (z Service Pack 2)
  • Microsoft.NET Framework
  • Microsoft Visual Studio®.NET
  • Windows Internet Explorer 5.0, lub nowszy

Natomiast przy sprawdzaniu klienta SOAP usług WWW napisanego w języku Visual Basic:

  • Microsoft Visual Basic 6.0
  • Microsoft XML Core Services 4.0 (MSXML)
  • Microsoft SOAP Toolkit 2.0 Service Pack 2

Instalacja aplikacji

Ustawienie Intranetu, by uruchomić aplikację, pociąga za sobą następujące zadania:

  • Instalacja plików aplikacji
  • Dołączenie plików bazy danych do serwera SQL Server 2000
  • Stworzenie wirtualnego katalogu IIS
  • Stworzenie wirtualnego katalogu SQLXML 3.0
  • Stworzenie nazwy wirtualnej SQLXML
  • Kompilacja projektu
  • Aktualizacja zmiennych konfiguracyjnych

Instalacja plików aplikacji

  1. Rozpakowanie pliku projects.zip i przeniesienie zawartości do katalogu C:\Projects.
  2. Po rozpakowaniu plików aplikacji będzie widoczna struktura katalogu − jak na przykładzie na rysunku 3.
Struktura katalogu System śledzenia projektów i zadań
Rysunek 3. Struktura katalogu System śledzenia projektów i zadań

Dołączanie plików bazy danych do serwera SQL Server 2000

  1. Po przejściu do folderu Projects, a następnie do Components należy otworzyć folder Database, a następnie rozpakować plik DatabaseFiles.zip, zawierający pliki.MDF and.LDF, które trzeba dołączyć do serwera SQL Server 2000.
  2. Uruchomić program Enterprise Manager (wchodzi w skład serwera SQL Server 2000), i rozwinąć węzeł Server.
  3. Kliknąć prawym przyciskiem myszy Bazę danych (Databases), wybrać Wszystkie zadania (All Tasks), a następnie Dołącz bazę danych (Attach Database).

Tworzenie wirtualnego katalogu IIS

  1. Uruchomić Menedżera Usług Internetowych (Internet Services Manager).
  2. Utworzyć nowy katalog wirtualny, nazwać go Projects i wskazać jego katalog źródłowy na C:\Projects\Web.

Zamiast tego, można wykonać następujące operacje:

  1. W C:\Projects kliknąć prawym przyciskiem na folder Web folde i wybrać Właściwości (Properties).
  2. Wybrać zakładkę Udostępnianie w sieci (WebWeb Sharing), a następnie Udostępnij ten folder (Share this folder).
  3. Zmienić nazwę z Web na Projects.

Tworzenie wirtualnego katalogu SQLXML 3.0

  1. W menu Start wybrać Programy, następnie SQLXML 3.0 i kliknąć ConRysunek IIS Support.
  2. Uruchomić IIS Virtual Directory Management for SQLXML 3.0.
  3. Stworzyć nowy katalog wirtualny SqlXml z nazwą ProjectsSQLVirDir. Podłączyć nowy katalog wirtualny do C:\Projects\SQLVirDir. W oknie właściwości ProjectsSQLVirDir, w zakładce Security w polu User Name i Password wpisać swoją nazwę użytkownika i hasło do SQL Servera.
  4. W zakładce Data Source wybrać instancję SQL Servera, do którego należy podłączyć bazę danych.
  5. Wybrać bazę danych Projects w polu Database.
  6. W zakładce Settings zaznaczyć pola wyboru Allow template queries i Allow POST.
Tworzenie wirtualnego katalogu SQLXML
Rysunek 4. Tworzenie wirtualnego katalogu SQLXML

Tworzenie wirtualnej nazwy SQLXML

  1. W oknie Właściwości ProjectsSQLVirDir w zakładce Virtual Names w polu Name należy wpisać Templates.
  2. W polu Type wpisać template.
  3. W polu Path wpisać C:\Projects\SQLVirDir\Template.

Kompilacja projektu

  1. Należy otworzyć projekt ProjTaskTrackSystem.sln w Visual Studio.NET.
    Ten projekt zawiera dwa podprojekty: Components i ProjTrackWeb. W pierwszej kolejności należy skompilować projekt Components, a następnie dodać do niego odniesienie (reference) w projekcie ProjTrackWeb.
  2. W projekcie ProjTrackWeb kliknąć prawym przyciskiem References.
  3. Wybrać Add Reference.
  4. Wskazać plik Components.dll i dodać odniesienie (reference).

Aktualizacja zmiennych konfiguracyjnych

Plik Web.config w projekcie ProjTrackWeb definiuje dwie zmienne. Pierwsza zawiera informacje o połączeniu z serwerem SQL Server 2000 (connection string), druga − ścieżkę do katalogu, gdzie znajdują się pliki szablonów XML i diagramy aktualizacji. Należy tu poprawić zmienne konfiguracyjne na właściwe połączenie z bazą danych oraz właściwą ścieżkę do katalogu z szablonami.

Uruchamianie przykładowej aplikacji

Strona default.aspx jest wczytywana domyślnie; używa ona pliku cookie do sprawdzenia, czy pracownik odwiedza stronę po raz pierwszy. Jeżeli plik cookie nie zostanie znaleziony, przeglądarka będzie przekierowana do strony firstvisit.aspx.

Wstępny widok dla użytkownika pierwszy raz odwiedzającego stronę
Rysunek 5. Wstępny widok dla użytkownika pierwszy raz odwiedzającego stronę

Do uruchomienia przykładowej aplikacji należy użyć jednego z e-maili z przykładowych danych pracownika. Adresy e-mail są sprawdzane na podstawie danych pracowników z tablicy tblEmployees. Jeżeli zostaną znalezione pasujące rekordy, tablica tblEmpPreferences jest przeszukiwana w celu uzyskania preferencji pracownika. Na podstawie tych ustawień pracownik jest przekierowywany do zakładki Projekty (Projects) lub zakładki Zadania (Tasks). Jeżeli nie zostaną znalezione żadne preferencje, pracownik zostanie przekierowany domyślnie do zakładki Projekty.

Zakładka Projekty (Projects)
Rysunek 6. Zakładka Projekty (Projects)

Chcąc utworzyć nowy projekt, pracownik musi kliknąć New Project, który otwiera okno dialogowe New Project (rysunek 7).

Okno dialogowe Nowy Projekt (New Project)
Rysunek 7. Okno dialogowe Nowy Projekt (New Project)

W celu edycji istniejącego projektu lub przeglądania zadań dla projektu pracownik klika rekord projektu w polu Title w zakładce Project, które otwiera okno dialogowe Edit Project (rysunek 8).

Okno dialogowe edycja projektu (Edit Project)
Rysunek 8. Okno dialogowe edycja projektu (Edit Project)

Zakładka Tasks jest podobna do zakładki Projects. Użytkownik może zobaczyć listę zadań i nacisnąć New Task, by stworzyć nowe zadanie lub kliknąć pojedyncze zadanie w polu Title w celu edycji.

Zakładka Zadania (Tasks)
Rysunek 9. Zakładka Zadania (Tasks)

Zakładki Projects i Tasks udostępniają pola na dole strony, które pozwalają pracownikowi na filtrowanie oglądanej listy projektów i zadań. System pozwala na selektywne wybieranie danych według właściciela, statusu, priorytetu i wydziału. Ustawienia tego filtra zapisywane są w tablicy tblEmpPreferences.

Wygląd listy projektów filtrowanej po właścicielu
Rysunek 10. Wygląd listy projektów filtrowanej po właścicielu

Zakładka Options (rysunek 11) umożliwia pracownikowi sprecyzowanie kolejnych ustawień, takich jak: pola sortowania dla projektów i zadań, początkową stronę (Projects lub Tasks), i włączenia i wyłączenia podglądu zarchiwizowanych lub anulowanych projektów lub zadań. Pozwala także na przełączanie pomiędzy użytkownikami poprzez kliknięcie Change.

Zakładka Options
Rysunek 11. Zakładka Options

Zakładka Admin pozwala administratorowi na zarządzanie tablicami bazy danych (polami tablic Employees, Departments, Status Codes i Priority Codes). Rysunek 12 pokazuje stronę Employees.

Zakładka administratora (Admin)
Rysunek 12. Zakładka administratora (Admin)

Components.dll

Components.dll (przestrzeń adresowa Projects.Components) zawiera klasy, które obudowują dostęp do danych, obsługę błędów i funkcjonalność XPath/XSLT (rysunek 13). Plik ErrorHandler.vb natomiast zawiera jedną współdzieloną (statyczną) metodę, nazwaną Log, która dodaje wiadomość do dziennika zdarzeń systemu Windows.

Pliki klas w projekcie komponentów Visual Basic .NET
Rysunek 13. Pliki klas w projekcie komponentów Visual Basic .NET

Pliki tblXXXX.vb udostępniają metody dostępowe do poszczególnych tabel bazy danych. Wszystkie te metody używają klasy DBAccess do wywołania pliku szablonu XML lub diagramu aktualizującego, mających dostęp do danych.

Klasa DBAccess

Klasa DBAccess używa zarządzanych klas SQLXML do wywołania szablonów XML i diagramów aktualizacji. Konstruktor klasy pierwszy otrzymuje ciąg połączenia do bazy danych z pliku Web.config i następnie inicjuje prywatną składową zmiennej SqlXmlCommand przez pokazanie ciągu połączenia.

Imports System
Imports System.Collections
Imports System.IO
Imports System.Configuration
Imports Microsoft.Data.SqlXml
Imports System.Xml
Imports System.Xml.XPath
Namespace Projects.Components
  Public Class DBAcess
    Private SQLDBConnStr As String
    Private TemplatesDir As String
    Private SqlXmlCmdObj As SqlXmlCommand

    'Konstruktor: Inicjalizacja
    Public Sub New()
      Try
        SQLDBConnStr = ConfigurationSettings.AppSettings("DBConnStr")
        TemplatesDir = ConfigurationSettings.AppSettings("SQLXMLTemplatesDir")
        SqlXmlCmdObj = New SqlXmlCommand(SQLDBConnStr)
      Catch e As Exception
        ErrorHandler.Log(e.ToString())
      End Try
    End Sub

Użycie współdzielonej właściwości AppSettings klasy ConfigurationSettings pozwoli na otrzymanie połączenia z bazą danych i wartości SQLXMLTemplatesDir. Następnie należy utworzyć obiekt SqlXmlCommand i przydzielić go do lokalnej zmiennej. Obiekt SqlXmlCommand jest używany w pozostałych metodach klasy do udostępnienia funkcjonalności SQLXML.

Klasa DBAccess zawiera metody, które pozwalają na wykonywanie szablonów SQLXML. Szablony te są używane do uruchamiania zapytań i pobierania danych w formacie XML lub do uruchamiania diagramów aktualizacji i modyfikacji bazy danych. Metoda ExecuteTemplate pobiera szablon jako ciąg znaków podany w parametrze. Metoda ExecuteTemplateFile pobiera plik szablonu XML, który zawiera zapytanie SQL lub tekst diagramu aktualizacji.

'Uruchomienie tekstu szablonu – brak parametrów (Execute Template text - no parameters)
Public Function ExecuteTemplate(ByVal TemplateText As String) As String
  SqlXmlCmdObj.CommandType = SqlXmlCommandType.Template
  SqlXmlCmdObj.CommandText = TemplateText

  Return RunTemplate()
End Function

'Uruchomienie pliku szblonu (no parameters)
Public Function ExecuteTemplateFile(ByVal TemplateFile As String) As String
  SqlXmlCmdObj.CommandType = SqlXmlCommandType.TemplateFile
  SqlXmlCmdObj.CommandText = TemplatesDir & TemplateFile

  Return RunTemplate()
End Function

Obie te metody są przeciążone w celu pobrania kolekcji obiektów, potrzebnych do przekazania parametrów do szablonów SQLXML. Przeciążone metody używają klasy SqlXmlParameter do stworzenia parametrów i ustawienia ich nazw i wartości. Poniżej znajduje się dodatkowy kod w przeciążonych metodach, które umożliwiają przekazywanie parametrów w trakcie wykonywania szablonów SQLXML:

Dim ParamEnum As IDictionaryEnumerator = Params.GetEnumerator()
While ParamEnum.MoveNext()
  Dim aParam As SqlXmlParameter = SqlXmlCmdObj.CreateParameter()
  aParam.Name = ParamEnum.Key
  aParam.Value = ParamEnum.Value
End While

Uruchamianie szablonu i sprawdzanie błędów wykonywane jest we wspólnej funkcji, nazwanej RunTemplate, znajdującej się w klasie DBAccess.

Private Function RunTemplate() As String
  Try
    Dim ResultStream As Stream
    Dim ResultString As String

    ResultStream = SqlXmlCmdObj.ExecuteStream()
    Dim SR As New StreamReader(ResultStream)
    ResultString = SR.ReadToEnd()
    'Sprawdzenie błędów
    Try
      Dim ResultStrReader As New StringReader(ResultString)
      Dim ResultXmlReader As New XmlTextReader(ResultStrReader)

      Do While ResultXmlReader.Read()

       If ResultXmlReader.NodeType = XmlNodeType.ProcessingInstruction Then
         If ResultXmlReader.Name = "MSSQLError" Then
           ErrorHandler.Log(ResultXmlReader.Value)
         End If

       End If
      Loop
    Catch
    End Try
    Return ResultString
   Catch e As Exception
     ErrorHandler.Log(e.ToString())
     Return "<Error>" & e.ToString() & "</Error>"
   End Try
End Function

Klasa SqlXmlCommand uruchamia metodę ExecuteStream, która służy do wykonania szablonu i pobrania wyników − jako nowy obiekt typu strumień danych. Ważne jest, by zapamiętać, że jeżeli wykonanie szablonu się nie uda i wynikowy strumień danych zwróci błąd SQLXML, żaden wyjątek nie jest generowany, a błąd nie jest wywoływany. Powód tego jest taki, że z perspektywy .NET Framework wykonanie szablonu się powiodło, natomiast do użytkownika należy sprawdzenie zwróconego dokumentu XML, by zobaczyć, czy wykonanie szablonu się powiodło, czy nie.

Do obsługi błędów należy stworzyć obiekt XmlTextReader dla zwróconego strumienia danych XML i następnie sprawdzić, czy pokazała się instrukcja MSSQLError. Po jej znalezieniu należy zapisać informacje o błędzie w systemowym dzienniku zdarzeń Windows. Dla przykładu, jeżeli wykonany zostanie diagram aktualizujący dla komendy insert i jeżeli wykonanie to się nie powiedzie z powodu braku wymaganej kolumny – diagram aktualizujący zwróci ciąg znaków XML, który zawiera informacje z opisem błędu, ale .NET Framework nie wywoła wyjątku lub błędu, ponieważ wykonanie diagramu aktualizującego samo w sobie powiodło się.

Klasy tblXXXX

Components.dll zawiera pliki klas dla każdej tabeli w bazie danych Projects. Na przykład tblDepartments.vb jest plikiem dla tabeli tblDepartments i tak dalej. Klasy tblXXXX używają klasy DBAccess dla wywołania plików szablonu i diagramów aktualizujących. Poniżej pokazano przykład, jak wygląda klasa tblDepartments.vb:

Namespace Projects.Components
  Public Class tblDepartments
    Private DBAccObj As New DBAcess()

    Public Function GetAllDepartments() As String
      Return DBAccObj.ExecuteTemplateFile("GetAllDepartments.xml")
    End Function

    Public Function GetDeptByID(ByVal Row_ID As String) As String
      Dim ParamsCollection As New Collections.Hashtable()
      ParamsCollection.Add("@Row_ID", Row_ID)
      Return DBAccObj.ExecuteTemplateFile("GetDeptByID.xml", _
        ParamsCollection)
    End Function

    Public Function Insert( _
      ByVal DataValues As Collections.Hashtable) As String
      Return DBAccObj.ExecuteTemplateFile("InsertDept.xml", DataValues)
    End Function

    Public Function Update(_
      ByVal DataValues As Collections.Hashtable) As String
      Return DBAccObj.ExecuteTemplateFile("UpdateDept.xml", DataValues)
    End Function

    Public Function Delete(ByVal Row_ID As Integer) As String
     Dim ParamsCollection As New Collections.Hashtable()
     ParamsCollection.Add("@Row_ID", Row_ID)
     Return DBAccObj.ExecuteTemplateFile("DeleteDepartment.xml",
       ParamsCollection)
   End Function
  End Class
End Namespace

Metoda GetAllDepartment wywołuje metodę ExecuteTemplateFile w klasie DBAccess, przekazując nazwę pliku szablonu XML (GetAllDepartments.xml), który ma zostać wykonany. Oto jak wygląda plik szablonu GetAllDepartments.xml:

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
        <!--All Departments-->
        <sql:query>
                SELECT * FROM tblDepartments FOR XML AUTO
        </sql:query>
</ROOT>

Plik szablonu zawiera zapytanie SELECT w tabeli tblDepartments i używa klauzuli FOR XML AUTO, która informuje procesor zapytania, by zwrócił wyniki jako strumień XML w miejsce rekordów (dopóki opcja Run on the client jest wybrana, oznacza to,że konwersja jest wykonywana po stronie klienta zamiast po stronie serwera SQL Server).

Podobnie, metody Insert, Update, Delete, i GetDeptByID używają klasy DBAccess i wykonują poszczególne diagramy aktualizacji lub pliki szablonów przekazując parametry, jeżeli są wymagane.

Pozostałe klasy tblXXXX wyglądają podobnie jak przykład z plikiem klasy tblDepartments.vb przedstawionym wcześniej.

Poniższy kod jest przykładem tego, jak parametry są przekazywane do szablonów SQLXML. Klasa tblProjects zawiera metodę, nazwaną GetProjectDetails, która pobiera ProjectRowID jako parametr i przekazuje go do pliku GetProjectDetails.xml − szablonu SQLXML.

Public Function GetProjectDetails(ByVal ProjectRowID As String) _
    As String
  Dim ParamsCollection As New Collections.Hashtable()
  ParamsCollection.Add("@ProjectRowID", ProjectRowID)
  Return DBAccObj.ExecuteTemplateFile("GetProjectDetails.xml", _
  ParamsCollection)
End Function

A oto przykład, jak wygląda plik GetProjectDetails.xml:

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<!--A Project Details-->
<sql:header>
<sql:param name="ProjectRowID"></sql:param>
</sql:header>
<sql:query>
SELECT *,
CONVERT(varchar(10), tblProjects.StartDate, 101) as StartDate1,
CONVERT(varchar(10), tblProjects.DueDate, 101) as DueDate1
FROM tblProjects
WHERE Row_ID = @ProjectRowID
FOR XML AUTO
</sql:query>
</ROOT>

Domyślnie klauzula FOR XML zwraca wartości typu data w formacie 2002-03-01T00:00:00. Poprzedni plik szablonu używa funkcji CONVERT języka Transact-SQL, by otrzymać datę w formacie mm/dd/yyyy. Ten plik szablonu przyjmuje parametr ProjectRowID, dla którego żądane są szczegóły projektu.

Mimo że wirtualna nazwa szablonów została stworzona wcześniej, ta nazwa właściwie nie jest użyta w kodzie. Klasy zarządzające SQLXML są używane i fizyczna ścieżka plików szablonów jest do nich przekazywana, często jednak dobrym pomysłem jest stworzenie wirtualnej nazwy typu template do wypróbowania szablonów z przeglądarki bez pisania żadnego kodu.

Reasumując: klasa DBAccess ułatwia uruchamianie szablonów i diagramów aktualizujących (bezpośrednich ciągów znaków lub plików) i zwraca wyniki jako ciąg znaków XML, na którym można zastosować arkusz stylów (stylesheet) i wysłać przekształcone w HTML do klienta.

Utility.vb

Klasa Utility zawiera metody stosowania arkuszy stylów XSLT i rozwiązywania wyrażeń XPath. Dla przykładu pokazano metodę ApplyXSL klasy Utility:

Public Function ApplyXSL(ByVal XMLText As String, _
    ByVal XSLFileName As String) As String
  Try
    Dim XSLTObj As New XslTransform()
    XSLTObj.Load(XSLFileName)
    Dim StringReaderObj As New StringReader(XMLText)
    Dim SourceXMLDoc As New XPathDocument(StringReaderObj)
    Dim StringWriterObj As StringWriter = New StringWriter()
    XSLTObj.Transform(SourceXMLDoc, Nothing, StringWriterObj)
    Return StringWriterObj.ToString()
  Catch e As Exception
    ErrorHandler.Log(e.ToString())
  End Try
End Function

W tej aplikacji klasa DBAccess jest użyta do wywołania szablonu SqlXml, który zwraca ciąg znaków XML jako wynik uruchomienia szablonu. Plik arkusza stylów XSLT jest następnie użyty do przekształcenia ciągu znaków XML w kod HTML. Dla tej konwersji została użyta metoda ApplyXSL. Ta metoda pobiera dwa parametry − ciąg znaków XML i nazwę pliku XSLT. Zwraca przekształcony tekst, który można następnie przesłać do klienta, używając metody Response.Write w kodzie pliku .aspx.

Ta metoda używa instancji klasy XslTransform do wczytania arkusza stylów i klasy XpathDocument do wczytania źródłowego ciągu znaków XML. Wywołanie metody Transform zwraca obiekt StringWriter zawierający przekształcony tekst, który następnie jest zwracany do wywołującego jako ciąg znaków.

Metoda ApplyXSL jest przeciążana w celu pobrania parametrów XSLT na wejściu i przekazania tych parametrów do arkusza stylów XSLT. Dodatkowy parametr dla ApplyXSL jest przekazany ponownie jako kolekcja HashTable, która zawiera pary: nazwa-wartość parametrów XSLT. Oto dodatkowy kod w przeciążonej metodzie ApplyXSL:

Dim XSLParams As New XsltArgumentList()
Dim ParamEnum As IDictionaryEnumerator = Params.GetEnumerator()
While ParamEnum.MoveNext()
   XSLParams.AddParam(ParamEnum.Key, "", ParamEnum.Value)
End While
XSLTObj.Transform(SourceXMLDoc, XSLParams, StringWriterObj)

Aby zbudować listę parametrów która ma być przekazana do arkusza styli XSLT, należy użyć klasy XsltArgumentList. Instancja XsltArgumentList jest przekazywana do metody Transform, która następnie przekazuje listę parametrów do arkusza stylów.

Następną użyteczną funkcją klasy Utility jest EvalXPathExpr która pozwala na zapytanie o pojedynczy węzeł XML i odczytanie jego wartości. Ta metoda pobiera źródłowy tekst XML na wejściu oraz wyrażenie XPath i zwraca albo wartość węzła, jeżeli zostanie znaleziona, albo pusty ciąg znaków.

Public Function EvalXPathExpr(ByVal XMLText As String, ByVal XPathExpr As String) As String
  Try
   Dim StringReaderObj As New StringReader(XMLText)
   Dim SourceXMLDoc As New XPathDocument(StringReaderObj)
   Dim XPathNavObj As XPathNavigator = SourceXMLDoc.CreateNavigator()
   Dim ResultNodes As XPathNodeIterator
   ResultNodes = XPathNavObj.Evaluate(XPathExpr)
   Dim ReturnValue As String
   If ResultNodes.Count = 1 Then
     ResultNodes.MoveNext()
     ReturnValue = ResultNodes.Current.Value.ToString()
     Return ReturnValue
   Else
     Return ""
   End If
 Catch e As Exception
   ErrorHandler.Log(e.Message)
   Return ""
 End Try
End Function

Poprzednia metoda używa klas StringReader i XPathDocument do wczytania źródłowego ciągu znaków XML. Następnie XPathNavigator jest stworzony dla obiektu XPathDocument. Potem metoda Evaluate klasy XPathNavigator jest wykonywana do przekazania wyrażenia XPath. Funkcja EvalXPathExpr używa wejściowego wyrażenia XPath do wybrania pojedynczego pasującego węzła. Jeśli został znaleziony pasujący węzeł XML, zwracana jest jego wartość.

Jeżeli zostało znalezionych więcej pasujących węzłów lub nie znaleziono żadnego, zwracany jest pusty ciąg znaków.

Aplikacja ASP.NET

Projekt TrackWeb jest aplikacją WWW ASP.NET, która została napisana za pomocą języka Visual Basic .NET. Zawiera formularze WWW i ich pliki, kod obsługujący stronę ASPX, arkusze stylów XSLT, plik Web.config, rysunki oraz podfoldery. Formularze WWW są używane do prezentacji list projektów i zadań, do dodania nowego projektu lub zadania, do aktualizacji istniejącego projektu lub zadania i do ustawienia preferencji użytkownika. W następnym dziale zostanie omówione użycie Components.dll do wywołania istniejących plików szablonów, dynamicznych szablonów, diagramów aktualizujących i zastosowania arkuszy stylów XSLT.

Default.aspx

Przede wszystkim należy uruchomić pierwszą stronę default.aspx i znaleźć metodę Page_Load. (Z uwagi na skróty niektóre linie kodów zostały pominięte; trzeba więc przejrzeć pliki źródłowe, by zobaczyć pełne kody).

Imports Projects.Components
...
CookieVal = Request.Cookies("ProjTrack_EmpID").Value()
'If cookie not found, redirect to firstvisit.aspx (code ommited here)
'If cookie found:
Dim EmpObj As New tblEmployees()
Dim UtilityObj As New Utility()
Dim CurrentViewVal As String
CurrentViewVal = UtilityObj.EvalXPathExpr( _
  EmpObj.GetEmpPrefs(CookieVal), _
  "//tblEmpPreferences/@InitialView")
If CurrentViewVal = "1" Then
  Response.Redirect("taskslist.aspx")
Else
  Response.Redirect("projectslist.aspx")
End If

Poprzedzający kod sprawdza wartość ProjTrack_EmpID w pliku cookie (znacznik stanu klienta). Jeżeli wartość nie zostanie znaleziona, strona jest przekierowana do firstvisit.aspx. Jeśli wartość pliku cookie zostanie znaleziona, klasa tblEmployees zostanie użyta do odczytania ustawień pracownika przez wywołanie metody GetEmpPrefs. Metoda GetEmpPrefs wewnętrznie używa klasy DBAccess i szablonu GetEmpPrefs.xml − zwraca ona preferencje pracownika w ciągu znaków XML w celu ustalenia, czy przekierować pracownika do okna Projects, czy Tasks, a decyzja ta bazuje na kolumnie InitialView w tablicy tblEmpPreferences.

Następnym krokiem jest przekazanie preferencje pracownika w ciągu znaków XML i wyrażenie XPath //tblEmpPreferences/@InitialView do funkcji EvalXPathExpr. Na podstawie wartości zwróconej przez tę funkcję, kontrola jest przekazywana do okna Projects albo Tasks.

Formularz WWW firstvisit.aspx (Rysunek 6) przyjmuje adres e-mail i, jeżeli formularz zostaje wysłany, używa metody GetEmpIdFromEmail klasy tblEmployees,a następnie ustawia zwrócony EmpID w pliku cookie w komputerze pracownika.

Projectslists.aspx

Formularz WWW projectslist.aspx (rysunek 7) pokazuje listę projektów, które są posortowane stosownie do preferencji pracownika. Możliwe jest filtrowanie listy w polach: Właściciel (Owner), Wydział (Department), Priorytet (Priority) lub Status (Status). Strona .aspx zawiera standartowy tekst HTML i wywołuje metodę BuildProjectList kodu ukrytego z pliku projectslist.aspx.vb. Oto jak wygląda metoda Page_Load w pliku projectslist.aspx.vb:

Try
  EmpID = Request.Cookies("ProjTrack_EmpID").Value()
Catch
  Response.Redirect("firstvisit.aspx")
End Try
If (IsPostBack) Then
  UpdateFilterSettings()
End If

Poprzedzający kod w pierwszej kolejności sprawdza, czy pole ProjTrack_EmpID w pliku cookie jest obecne; jeżeli nie −przekierowuje do strony firstvisit.aspx.

Tabela tblEmpPreferences zawiera dwa pola (ProjFilterCriteria i TaskFilterCriteria), używane do przechowywania kryterium filtrowania Projektów (Projects) i Zadań (Tasks) na podstawie formatu:

<Filter>
  <FilterStatus>2</FilterStatus>
  <FilterDepartment>1</FilterDepartment>
  <FilterOwner>2</FilterOwner>
  <FilterPriority></FilterPriority>
</Filter>

Jeżeli pracownik wybierze pozycje z pola wyboru filtru w dolnej części zakładki Projektów lub Zadań i następnie kliknie Zastosuj Filtr (Apply Filter), metoda Page_Load w projectlist.aspx.vb wywoła lokalną metodę UpdateFilterSettings. Ta lokalna metoda stworzy ciąg znaków z diagramem aktualizującym, użyje klasy DBAccess do wykonania diagramu aktualizującego i zmodyfikuje (doda lub zmieni) rekord w tabeli tblEmpPreferences.

Private Sub UpdateFilterSettings()
  Dim UpdgStr As String
  Dim BeforeBlockStr As String
 
  Dim EmpObj As New tblEmployees()
  Dim UtilObj As New Utility()
  Dim Row_ID As String
 
  Row_ID = UtilObj.EvalXPathExpr(EmpObj.GetEmpPrefs(EmpID), _
    "//tblEmpPreferences/@Row_ID")
 
  If Row_ID.Length > 0 Then
    BeforeBlockStr = "<updg:before><tblEmpPreferences Row_ID='" & _
      Row_ID & "'/></updg:before>"
  End If
 
  UpdgStr = _
   "<ROOT xmlns:updg='urn:schemas-microsoft-com:xml-updategram'>" & _
      "<updg:sync >" & _
         BeforeBlockStr & _
         "<updg:after> <tblEmpPreferences " & _
          "EmpID='" & EmpID & "' ProjFilterCriteria='<Filter>" & _
          "<FilterPriority>" & _
          Request.Form("PriorityCodes") & "</FilterPriority>" & _
          "<FilterStatus>" & _
          Request.Form("StatusCodes") & "</FilterStatus>" & _
          "<FilterDepartment>" & _
          Request.Form("Departments") & "</FilterDepartment>" & _
          "<FilterOwner>" & _
          Request.Form("Employees") & "</FilterOwner>" & _
          "</Filter>' " & _
          "/>" & _
          "</updg:after>" & _
       "</updg:sync>" & _
  "</ROOT>"
 
  Dim DBAccObj As New DBAcess()
  DBAccObj.ExecuteTemplate(UpdgStr)
End Sub

Poprzedzająca funkcja dynamicznie tworzy ciąg znaków z diagramem aktualizującym i używa klasy DBAccess do wykonania diagramu do dodania lub zmiany rekordu z preferencjami użytkownika w tabeli tblEmpPreferences. Kod naświetla sposób dynamicznego tworzenia diagramu aktualizującego i jego wykonanie. Alternatywą budowania ciągu znaków diagramu aktualizacji jest użycie klasy StringBuilder do zamiany kosztownego łączenia ciągu znaków lub użycie zewnętrznego pliku diagramu aktualizacji i przekazanie do niego parametrów.

Metoda UpdateFilterSettings przede wszystkim używa metod tblEmployees.GetEmpPrefs i Utility.EvalXPathExpr do znalezienia rekordu z preferencjami pracownika. Jeżeli rekord istnieje, metoda tworzy blok, który jest używany do budowania ciągu znaków z diagramem aktualizacji. Bloki <updg:before /> i <updg:after /> służą bardziej operacji do aktualizacji niż do operacji dodawania.

W tym przypadku kosztowne operacje łączenia ciągów znaków mogą być zastąpione przez dwa zewnętrzne pliki diagramów aktualizacji. Przekazywanie parametrów może zostać użyte do dodawania lub zmiany rekordów w tabeli tblEmpPreferences, jednak w pewnych sytuacjach jedyną wykonywalną opcją jest zbudowanie szablonu lub diagramu aktualizacji dynamicznie. Przykładem jest zwrócenie listy projektów na podstawie warunków filtrowania i sortowania. Komenda SELECT języka Transact-SQL do wykonania, nie jest znana przed uruchomieniem, ponieważ nie jest możliwe, by w pliku szablonu XML było dynamicznie modyfikowane zapytanie SQL. Pozostaje więc dynamiczne zbudowanie ciągu znaków szablonu i wykonanie go.

Do zbudowania listy projektów bazujących na wybranych opcjach filtrowania strona projectslist.aspx wywołuje metodę BuildProjectList, obecną w pliku projectslist.aspx.vb ze ukrytym kodem. Metoda BuildProjectList na początku pobiera preferencje pracownika na podstawie wyszczególnionych preferencji, a następnie dynamicznie buduje ciąg znaków szablonu XML przy użyciu funkcji GetProjListTemplate, uruchamia ten szablon XML, który zwraca wynikowe dane jako ciąg XML, i stosuje arkusz stylów na zwróconym XML. (Kod został obcięty ze względu na czytelność; należy zajrzeć do kodów źródłowych, by zobaczyć kompletne kody).

Dim EmpObj As New tblEmployees()
Dim DBAccObj As New DBAcess()
Dim EmpPrefs As String

EmpPrefs = EmpObj.GetEmpPrefs(EmpID)
InitializeFilterMemberVars(EmpPrefs)
With Response
.Write("<table border='0' cellPadding='3' cellSpacing='1'>")
.Write("<tr class='tablehead'>")
.Write("<td valign='top' ><b>Title</b></td>")
...
.Write(UtilObj.ApplyXSL(DBAccObj.ExecuteTemplate( _
GetProjListTemplate(EmpPrefs)), _
Server.MapPath("Style/ProjList.xsl")))
...
.Write("<td valign='top' >" & _
UtilObj.StatusCodesComboBox(FilterStatus, _
Server.MapPath("Style/CBStatusCodes.xsl"), True) & "</td>")
...
End With

Metoda BuildProjectList tworzy listę Projektów stosownie do preferencji pracownika. Metoda zaczyna od wywołania metody tblEmployees.GetEmpPrefs, która zwraca ustawienia jako łańcuch znaków XML. Ten ciąg znaków jest przekazywany do funkcji składowej, nazwanej InitializeFilterMemberVars, która używa wyrażeń XPath i metody Utility.EvalXPathExpr do przetwarzania i odczytania ustawień filtra (tak samo jak ustawienia filtra są zapisane jako łańcuch znaków XML w polu ProjFilterCriteria w tabeli tblEmpPreferences).

Ważną linią w kodzie jest wywołanie funkcji składowej GetProjListTemplate, która zwraca szablon XML. Zawiera on dynamicznie utworzone zapytanie SELECT w języku Transact-SQL, bazujące na ustawieniach filtra i sortowania. Ciąg znaków szablonu XML zwrócony przez GetProjListTemplate przekazywany jest metodzie DBAccess ExecuteTemplate, która zwraca wyniki zapytania SELECT jako łańcuch znaków XML. Ostatecznie te wyniki przekazywane są do metody ApplyXSL, która generuje tekst HTML prezentujący szczegóły projektu.

Na koniec BuildProjectList wywołuje funkcje Utility do budowania pola wyboru filtra, które są położone w dolnej części zakładek Projects i Tasks. Pierwszy parametr dla tych wywołań jest indeksem wybranej pozycji w polu wyboru, drugim parametrem jest plik XSLT. Trzeci parametr jest opcjonalnym parametrem domyślnie ustawionym jest na False, który wskazuje, że tylko rekordy z poszczególnych tabel w wybranych polach będą wyświetlone. W metodzie BuildProjectList należy przekazać parametr jako True, co oznacza, że w polu wyboru zostanie dodana ekstrapozycja "−Any−", którą filtr może zostać usunięty.

Kod w taskslist.aspx.vb jest podobny do projectslists.aspx.vb.

Newproject.aspx

Jak była o tym mowa w poprzednich działach, lepiej wywoływać zewnętrzne szablony lub pliki diagramów aktualizujących i przekazywać do nich parametry, niż używać kosztownych połączeń łańcuchów znaków do budowania szablonów lub diagramów aktualizujących. Plik Newproject.aspx file (rysunek 8) jest znów formularzem WWW, który pozwala na dodanie nowego rekordu projektu w tabeli tblProjects.

Metoda Form_Load w pliku newproject.aspx.vb sprawdza, czy formularz został wysłany (właściwość IsPostBack jest ustawiona true). Wykonuje ona funkcję członkowską AddNewProject, która wygląda następująco:

Private Sub AddNewProject()
 Dim ProjObj As New tblProjects()
 Dim DataValues As New Hashtable()
 With DataValues
   .Add("@Title", Title.Text)
   .Add("@Description", Description.Text)
   If Convert.ToInt32(PercentComplete.Text) >= 100 Then
     .Add("@PercentComplete", "100")
   Else
     .Add("@PercentComplete", PercentComplete.Text)
   End If
   If Request.Form("Employees") = "" Then
    .Add("@Owner", "1")
   Else
    .Add("@Owner", Request.Form("Employees"))
   End If
   .Add("@StartDate", Request.Form("StartDate"))
   .Add("@DueDate", Request.Form("DueDate"))
   .Add("@StatusCode", Request.Form("StatusCodes"))
   .Add("@DeptCode", Request.Form("Departments"))
   .Add("@PriorityCode", Request.Form("PriorityCodes"))
   .Add("@CreatedBy", Request.Form("CreatedBy"))
 End With

 ProjObj.InsertProject(DataValues)
End Sub

Poprzedzająca metoda tworzy instancję klasy HashTable i dodaje pary: nazwa–wartość dla każdego pola w formularzu WWW, następnie przekazuje ten obiekt HashTable do metody InsertProject klasy tblProjects. Metoda InsertProject używa metody ExecuteTemplateFile klasy DBAccess, przesyłając InsertProject.xml jako nazwę szablonu (plik diagramu aktualizującego) i kolekcję parametrów jako drugi parametr. Oto jak wygląda plik InsertProject.xml diagramu aktualizującego:

<ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">
<!-- Add (Insert) a project -->
<updg:header>
        <updg:param name="Title"></updg:param>
        <updg:param name="Description"></updg:param>
        <updg:param name="CreatedBy"></updg:param>
        <updg:param name="Owner"></updg:param>
        <updg:param name="StartDate"></updg:param>
        <updg:param name="DueDate"></updg:param>
        <updg:param name="StatusCode"></updg:param>
        <updg:param name="DeptCode"></updg:param>
        <updg:param name="PriorityCode"></updg:param>
        <updg:param name="PercentComplete"></updg:param>
</updg:header>
<updg:sync >
<updg:after updg:returnid="Row_ID">
<tblProjects updg:at-identity="Row_ID"
        Title="$Title"
        Description="$Description"
        Owner="$Owner"
        PercentComplete="$PercentComplete"
        StartDate="$StartDate"
        DueDate="$DueDate"
        StatusCode="$StatusCode"
        DeptCode="$DeptCode"
        PriorityCode="$PriorityCode"
        CreatedBy="$CreatedBy"
/>
</updg:after>
</updg:sync>
</ROOT>

Plik Newtask.aspx zawiera kod podobny do kodu w pliku Newproject.aspx. Editproject.aspx i Edittask.aspx pliki zawierają również podobne kody i używają klas Components.dll do wykonywania szablonów, a także stosują arkusze stylów. Warto poświęć trochę czasu na przejrzenie kodów w tych plikach i plikach arkuszy stylów w katalogu Style.

Admin.aspx

Zakładka Admin wylicza tabele bazy danych Projects i także pozwala menedżerowi na dodawanie, edycje i usunięcie rekordów. Do wyświetlania i rekordów ASP.NET udostępnia rozszerzalną i elastyczną kontrolkę DataGrid.

Rysunek 14 pokazuje użycie SQLXML do uzyskania danych w formacie XML i następnie podłączenie ich do DataGridu ASP.NET.

Podłączanie danych XML zwróconych przez SQLXML
Rysunek 14. Podłączanie danych XML zwróconych przez SQLXML

Strona ASPX zawiera kontrolkę dataGrid, nazwaną TableListGrid, która zawiera dwie kolumny ułatwiające edycję i usunięcie wiersza tabeli:

<asp:datagrid id="TableListGrid" runat="server" ...>
<AlternatingItemStyle BackColor="Ivory" />
<Columns>
        <asp:ButtonColumn Text="Edit" CommandName="Select">
                <ItemStyle ForeColor="Black"></ItemStyle>
        </asp:ButtonColumn>
        <asp:ButtonColumn Text="Remove" CommandName="Delete">
                <ItemStyle ForeColor="Black"></ItemStyle>
        </asp:ButtonColumn>
</Columns>
</asp:datagrid>

Poniżej przedstawiony jest sposób podłączenia danych XML zwróconych przez SQLXML w poprzedniej kontrolce DataGrid:

Private Sub EmployeesList()
  lblTableName.Text = "Employees"
  Dim EmpObj As New tblEmployees()
  ShowTableList(EmpObj.GetAllEmployeesVerbose())
End Sub

Private Sub ShowTableList(ByVal TableData As String)
  Dim objStringReader As New StringReader(TableData)
  Dim objDS As New DataSet()
  objDS.ReadXml(objStringReader)

  If objDS.Tables.Count > 0 Then
    TableListGrid.DataSource = objDS
    TableListGrid.DataBind()
    TableListGrid.DataKeyField = "Row_ID"
    TableListGrid.Visible = True
  Else
    TableListGrid.Visible = False
  End If
End Sub

Metoda EmployeeList używa klasy tblEmployees i wykonuje jej metodę GetAllEmployeesVerbose, która zwraca szczegóły o pracowniku jako ciąg znaków XML.

Łańcuch znaków XML należy przekazać do metody ShowTableList, która używa obiektu StringReader do wczytania wejściowego tekstu XML do czytnika, a następnie stworzyć nowy obiekt DataSet i metodą ReadXml przekazać StringReader jako parametr wejściowy. Teraz dane pracownika wczytane są do obiektu DataSet. Następnym krokiem jest podłączenie obiektu DataSet do DataGrid poprzez użycie właściwości DataSource metody DataBind grid-a. Inicjując DataKeyField w ten sposób, że gdy operacje edycji i usuwania są wykonywane, otrzymujemy Row_ID wartości kolumny i używamy jej do znalezienia rekordu do edycji lub usunięcia.

Funkcjonalność dodawania, usuwania lub zmiany na tej stronie jest używana dla poszczególnych klas tblXXXX. Te klasy używają klasy DBAccess i wykonują pliki diagramów aktualizacji do wywołania modyfikacji bazy danych.

Wsparcie SOAP w SQLXML 3.0

Można zmienić przechowywane procedury w metody serwisów WWW przez kilka kliknięć myszką. To oznacza, że dowolny klient SOAP może wywołać przechowywaną procedurę po protokole HTTP i otrzymać wynik w formacie XML.

Aplikacja Visual Basic 6.0 jest załączona w tej aplikacji, która pozwala użytkownikowi na przeglądanie statystyk, projektów i zadań (np. liczba zadań w trakcie lub liczba zadań, które zostały ukończone). Aplikacja Visual Basic 6.0 używa Microsoft SOAP Toolkit 2.0 Service Pack 2 do wywołania metod serwisów WWW, które zwracają rezultaty jako obiekt IXMLDOMNodeList. Następnie Microsoft XML Core Services (MSXML) 4.0 jest używana do przetwarzania wyników.

Przechowywane procedury

Baza danych Projects zawiera i przechowuje dwie następujące procedury:

CREATE PROCEDURE sproc_GetEmpProjStatistics
  @EmailAlias AS VARCHAR(50)
AS
  SELECT a.StatusCode, count(*) as CountVal
  FROM
    tblProjects a JOIN tblEmployees b
    ON a.Owner = b.Row_ID
    WHERE b.EmailAlias = @EmailAlias
    GROUP BY a.StatusCode
GO

CREATE PROCEDURE sproc_GetEmpTaskStatistics
  @EmailAlias AS VARCHAR(50)
AS
  SELECT a.StatusCode, count(*) as CountVal
  FROM
    tblTasks a JOIN tblEmployees b
    ON a.Owner = b.Row_ID
    WHERE b.EmailAlias = @EmailAlias
    GROUP BY a.StatusCode
GO

Te przechowywane procedury zwracają kod statusu i zliczają projekty lub zadania w tej kategorii statusu.

Stworzenie wirtualnej nazwy typu soap

SQLXML 3.0 wprowadza jeszcze jeden typ wirtualnej nazwy − soap, w uzupełnieniu do istniejących typów dbobject, template i schema. Wirtualna nazwa z typem soap pozwala na konfigurację przechowywanych procedur, funkcji definiowanych przez użytkownika (UDFs) lub szablonów jako metod serwisów WWW. Proces konfiguracji generuje plik .wsdl i dodaje operacje WSDL do każdej przechowywanej procedury, UDF lub szablonu. Konfiguracje nazw wirtualnych z typem soap są zapisywane w pliku .ssc.

Do stworzenia nazwy wirtualnej typu soap i konfiguracji dwóch przechowywanych procedur jako metod serwisów WWW trzeba wykonać następujące operacje:

  1. Uruchomić narzędzia konfiguracji SQLXML 3.0 (Configure IIS Support tool).
  2. Kliknąć dwa razy wirtualny catalog ProjectsSQLVirDir, stworzony wcześniej.
  3. W zakładce Virtual Names w polu Name wpisać ProjectsWebSvc.
  4. W polu Type wpisać soap.
  5. W polu Path wpisać C:\Projects\SQLVirDir\SQLWebSvc.
  6. W polu Web Service Name wpisać ProjectsWebSvc (tę samą nazwę, jak nazwa wirtualna), jak pokazano na rysunku 15.
  7. Kliknąć save. Nowa wirtualna nazwa ukaże się w polu Defined virtual names.
Tworzenie wirtualnej nazwy typu soap
Rysunek 15. Tworzenie wirtualnej nazwy typu soap
  1. Wybrać ProjectsWebSvc w polu Defined virtual names i kliknąć Configure.
  2. Kliknąć przycisk SP/Template (), i wybrać procedurę sproc_GetEmpProjStatistics z listy przechowywanych procedur.
  3. W oknie dialogowym SOAP stored procedure mapping kliknąć OK.
  4. W oknie dialogowym SOAP virtual name configuration (rysunek 16), kliknąć Save.
Konfigurowanie wirtualnej nazwy soap
Rysunek 16. Konfigurowanie wirtualnej nazwy soap

Teraz należy powtórzyć poprzednie kroki, by wskazać przechowywaną procedurę sproc_GetEmpTaskStatistics. W oknie dialogowym Soap virtual name configuration obie nazwy przechowywanych procedur powinny być pokazane w polu Methods, jak pokazano na rysunku 17.

Procedury wbudowane udostępnione jako metody SOAP
Rysunek 17. Procedury wbudowane udostępnione jako metody SOAP
  1. Kliknąć OK.
  2. Następnie w oknie dialogowym Virtual Directory Manager kliknąć OK ponownie.

Konfiguracja stworzyła pliki .wsdl i .ssc. Plik .wsdl opisuje serwis i operacje, jakie będą używane z aplikacji klienckiej SOAP Toolkit. Plik .ssc jest zarządzany przez SqlXml; zawiera informację konfigurującą wirtualną nazwę typu soap.

Klient Visual Basic 6.0

Przechowywana procedura sproc_GetEmpProjStatistics i sproc_GetEmpTaskStatistics są teraz dostępne jako metody SOAP. Można użyć Microsoft SOAP Toolkit do wywołania tych przechowywanych procedur (jako metody serwisu WWW) i przetwarzać zwrócone dane XML.

Aplikacja kliencka w Visual Basic 6.0, która została dostarczona z przykładową aplikacją, jest aplikacją typu tray icon. Po uruchomieniu aplikacji Visual Basic można zobaczyć okno dialogowe Projects/Tasks Tracking System Client i ikonę w pasku powiadomień (tray icon). Aby zakończyć – trzeba kliknąć prawym przyciskiem ikonę, a następnie wybrać Exit.)

Klient w Visual Basic 6.0
Rysunek 18. Klient w Visual Basic 6.0

Ta aplikacja odwołuje się do plików dll Microsoft SOAP Toolkit 2.0, Service Pack 2 Microsoft XML, Core Services (MSXML 4.0). Po skompilowaniu i przetestowaniu aplikacji klienckiej należy zapamiętać, by zaktualizować stałą WSDL URL w górze kodów:

Option Explicit
Const SQLXMLWebSvsWSDLURL = "http://sch02singhdnt/ProjectsSQLVirDir/ProjectsWebSvc?wsdl"

Kliknięcie Go w oknie dialogowym Projects/Tasks Tracking System Client wywoła metodę GetProjectAndTaskStatistics, która aktualnie inicjuje wywołanie SOAP i przetwarza odpowiedź.

Private Sub cmdGo_Click()
    GetProjectAndTaskStatistics
End Sub

Metoda GetProjectAndTaskStatistics rozpoczyna się deklaracją instancji klasy SoapClient z biblioteki narzędziowej SOAP i zmiennej typu IXMLDOMNodeList z biblioteki MSXML 4.0:

Private Sub GetProjectAndTaskStatistics()
    Dim retVal As Integer
    Dim objClient As New SoapClient
    Dim retNodeList As IXMLDOMNodeList

    Me.MousePointer = vbHourglass
    InitializeControls

Metoda InitializeControls zeruje etykiety rezultatów do "---", a następnie wywołuje metody mssoapinit i przesyła do nich adres WSDL URL. Wywołanie mssoapinit inicjuje obiekt SoapClient przez użycie pliku WSDL, tak że wszystkie operacje identyfikowane przez serwis mogą być dostępne przez użycie obiektu SoapClient.

    objClient.mssoapinit SQLXMLWebSvsWSDLURL

Teraz można wywoływać metody serwisu WWW, a przede wszystkim metodę do pobrania statystyk projektów:

On Error Resume Next
Set retNodeList = objClient.sproc_GetEmpProjStatistics( _
                            txtEmailAlias.Text, retVal)
With retNodeList.Item(0)
 lblCompleted.Caption = _
.selectSingleNode("//row[@StatusCode='3']").Attributes(1)
  .nodeTypedValue
 lblInProgress.Caption = _
.selectSingleNode("//row[@StatusCode='2']").Attributes(1)
  .nodeTypedValue
 lblNotStarted.Caption = _
.selectSingleNode("//row[@StatusCode='1']").Attributes(1)
  .nodeTypedValue
 lblOngoing.Caption = _
.selectSingleNode("//row[@StatusCode='5']").Attributes(1)
  .nodeTypedValue
End With

Kod pokazany powyżej wywołuje metodę sproc_GetEmpProjStatistics serwisu WWW i przekazuje do niej adres e-mail jako pierwszy parametr oraz liczbę typu integer, która zawiera zwrócony kod. Metoda sproc_GetEmpProjStatistics serwisu WWW zwraca obiekt IXMLDOMNodeList, zawierający wynik XML podobny do następującego:

<sqlresultstream:SqlXml
  xmlns:sqlresultstream="http://schemas.microsoft.com/SQLServer/2001/12/SOAP/types/SqlResultStream"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:type="sqltypes:SqlXml"
  xmlns:sqltypes="http://schemas.microsoft.com/SQLServer/2001/12/SOAP/types"
  sqltypes:IsNested="false">
<SqlXml>
  <row StatusCode="3" CountVal="1"/>
  <row StatusCode="2" CountVal="3"/>
</SqlXml>

Następnie należy użyć metody selectSingleNode, wyrażenia XPath i kolekcji Atrybutów do pobrania liczb dla rozmaitych kodów statusu, to samo − dla statystyk zadań. Teraz należy wywołać metodę sproc_GetEmpTaskStatistics serwisu WWW, wyrażenia XPath i kolekcję Atrybutów do pobrania liczb dla rozmaitych kodów statusu.

Zakończenie

XML i wsparcie Microsoft.NET Framework w serwerze SQL Server 2000 może uprościć proces tworzenia aplikacji. W uzupełnieniu, aplikacje budowane przy użyciu SQL Server 2000, XML i Visual Basic .NET mogą być zmienione w serwisy WWW, które następnie mogę być dostępne z dowolnej platformy i dowolnego języka. W ostatnim przykładzie pokazano nawet w jaki sposób można skorzystać z tych możliwości za pomocą kodu w Visual Basic 6.0 dzięki użyciu Microsoft SOAP Toolkit.

Spis treści

Pobierz pełny kod przykładu: ProjTrackSystemCode.zip


Podobne artykuły

Komentarze 0 Masz uwagi do tej strony? Napisz

Dodaj komentarz

avatar

Zaloguj się lub Zarejestruj się aby wykonać tę czynność.

Autor Jacek Kolonko
avatar VIP
 

What do you want to write today? ;)

Załóż konto
WSS to serwis, który łączy dziesiątki tysięcy specjalistów IT w Polsce, zajmujących się szeroko pojętymi technologiami Microsoft. Portal działa od 2003 roku, i oprócz setek publikacji technicznych, rozwijającego się forum - portal to ludzie, którzy go tworzą. To właśnie z myślą o nich warto codziennie nas odwiedzać.

Dowiedz się więcej o WSS

vGuru - Zostań Guru Wirtualizacji

 

MetroOne

Idź na górę strony