1. beadandó feladat dokumentáció Készítette: Speeder
Feladat: Készítsünk egy blogkezelo˝ honlapot, amelyen a felhasználók saját blogokat vezethetnek. A weblap rendelkezzen az alábbi funkciókkal: ˝ • A fooldalon listázódnak a blogok (név, létrehozó, utolsó bejegyzés dátuma, utolsó 3 bejegyezés címe), a szerint, ˝ mikor frissítették utoljára, valamint lehetoség van keresésre blog létrehozója, illetve a bejegyzés cím(részlet)ére, továbbá szukíthetjük ˝ találatokat dátum intervallum alapján. Egy oldalon maximum 5 blog szerepelhet, utána lapozni kell. • A blogot kiválasztva egymás alatt megjelennek az írások (elso˝ kb. 500 karaktere úgy, hogy egész mondatok szerepeljenek) a létrehozás dátuma szerint, egy oldalon maximum 5 bejegyzés jelenik meg, utána lapozni kell. A címre kattintva megjelenik a teljes blogbejegyzés, a képpel együtt (ha van), valamint, hogy kiknek tetszett a bejegyzés. ˝ • A felhasználóknak eloször regisztrálniuk kell a felhasználónév, jelszó, e-mail cím, profilkép, valamint blog címe ˝ megadásával, ezután bejelentkezhetnek. Bejelentkezve megkapják a saját blogjukat, ahol lehetoségük van új ˝ bejegyzés létrehozására, korábbi írás módosítására/törlésére, valamint kijelentkezésre. Legyen lehetoség a bejelentkezés eltárolására, hogy legközelebb ne kelljen újra bejelentkezni. • Íráskor meg kell adniuk a címet, a szöveget, valamint mellékelhetnek egy képet, amely automatikusan kicsinyítésre kerül, ha túl nagy az oldal szerkezetének. • A felhasználók lájkolhatják mások bejegyzéseit. Egy felhasználó egy bejegyzést maximum egyszer. Az adatbázis az alábbi adatokat tárolja (ezek még nem feltétlenül a fizikai adattáblák): • felhasználók (felhasználónév, jelszó, e-mail, profilkép, blog címe); Webes alkalmazások fejlesztése 2011/2012 tavaszi félév 10 • bejegyzések (felhasználónév, bejegyzés címe, bejegyzés szövege, kép). • lájkolások (felhasználónév, bejegyzés).
Elemzés: • A felületen a felhasználó egy a fejlécben lévo˝ menüben választhat az oldal fo˝ funkciói közül. Itt érheto˝ el a re˝ gisztrációs és bejelentkezési felület illetve a navigációs gombok amik a fooldalhoz és a keresés oldalhoz vezetnek. ˝ ˝ Bejelentkezést követoen itt látható a bejelentkezett felhasználó neve, valamint lehetoség van kijelentkezésre is. A felhasználónevet és a jelszót automatikusan megjegyeztetjük, így a kijelentkezésig nem kell a felhasználónak újra bejelentkeznie. • Külön urlapokat ˝ biztosítunk a regisztrációra, bejelentkezésre, kijelentkezésre, keresésre, blog és blogbejegyzés ˝ ˝ listázásra, bejegyzés olvasásra és szerkesztésre. Minden urlapon ˝ validátorok segítségével ellenorizzük a mezok helyes kitöltését. • A felhasználó tevékenységeit (regisztráció, bejelentkezés) a háttérben naplózzuk.
1
uc UseCaseDiagram
Registration
Search Blogs User
Browse Blogs Read Own Blog
«precedes»
Log Out
ReadBlog «precedes»
«Precedes»
«precedes» «precedes» «precedes»
Log In ReadEntry CreateEntry DeleteEntry EditEntry
1. ábra. Felhasználási esetek diagram
Adatbázis tervezés: Az adatbázisban öt táblát tárolunk. A képeket bináris formában tároljuk. • A felhasználó (User) tábla tárolja a felhasználó információit: név, e-mail cím, jelszó, avatar-kép, admin-jogosultság. A felhasználó jelszavát és avatar-képét binárisan tároljuk. • A blog (Blog) tábla tárolja a blogokkal kapcsolatos infórmációkat (azonosító, név) és kapcsolódik a felhasználó táblához. • A bejegyzés (Entry) tábla tárolja az egyes blog bejegyzések információit (cím, dátum, szöveg, kép), és kapcsolódik a blog táblához. • A kedvelés (Like) tábla tárolja a felhasználók és bejegyzések like összefüggéseit, így kapcsolódik a felhasználó és bejegyzés táblákhoz. • Az eseménynapló (UserLog) táblában a felhasználóhoz kötve tároljuk a bejegyzés idejét, a tevékenység típusát, valamint az esetleges üzenetet.
Szerkezeti tervezés: ˝ • A weblapot a modell/nézet architektúrának megfeleloen építjük fel, ahol a modell réteg megfelelo˝ típusok segítségével szolgáltatja az információkat a felületnek. A modell egy entitásmodellen keresztül tartja a kapcsolatot az adatbázissal. Logikai réteg (Model névtér): • Az adatbázissal való kommunikációt a DataManager statikus osztály gyujti ˝ egybe, amely lefedi a teljes entitásmodellt. A lekérdezéseket és transzformációkat LINQ kifejezésekkel valósítjuk meg. Az alfanumerikus tartalmat 2
UserLog
User
Properties
Blog
Properties
Properties
Id : Int32
Id : Int32
Id : Int32
LogTime : DateT…
Name : String
Name : String
LogType : String LogMessage : St… UserId : Int32 Navigation Properties User
*
1
Password : Binary
1
*
EMail : String
UserId : Int32 Navigation Properties
Avatar : Binary
User
IsAdmin : Boolean
Entry
SessionId : Int32 1
Navigation Properties Blog Like Log
* 1
Entry
*
Properties
Like
BlogId : Int32 Id : Int32
Properties
Title : String
UserId : Int32
Date : DateTime
EntryBlogId : Int… EntryId : Int32 Navigation Properties User Entry
2. ábra. Adatbázis diagram
3
*
1
Text : String Image : Binary Navigation Properties Blog Like
cd ClassDiagram-Model «C# class»
«C# class»
«C# class»
«C# class»
«C# class»
AspBlog::App_Code::Model::DataNotFoundException
AspBlog::A…l::UserData
AspBlog::A…l::BlogData
AspBlog::A…::EntryData
AspBlog::A…SearchData
«C# class» AspBlog::App_Code::Model::DataSaveFailedException
«C# class» AspBlog::App_Code::Model::LikeDuplicationException
Attributes
Attributes
Attributes
Attributes
+ + + + + + +
+ + + + + +
+ + + + + + +
+ + + + + + +
Administrator : Boolean EMail : String HasAvatar : Boolean Id : Integer Name : String Password : String SessionId : Integer
Operations
Operations
«C# class»
Id : Integer LastDate : DateTime Name : String TitleList : List<String> UserId : Integer UserName : String
Operations
+ BlogData()
+ UserData()
AspBlog::App_Code::Mode…ameDuplicationException
BlogId : Integer Date : DateTime HasImage : Boolean Id : Integer Likers : List
Text : String Title : String
DateFilter : Boolean EndDate : DateTime EntryTitle : String MyBlogs : Boolean StartDate : DateTime UserId : Integer UserName : String
Operations
+ EntryData()
+ SearchData()
* *
*
*
«C# class» AspBlog::App_Code::Model::UserPasswordException
«C# class» AspBlog::App_Code::Model::DataLoadFailedException 1 «C# class» «C# class»
AspBlog::App_Data::UserLog * UserLog
1
1
«C# class»
1
AspBlog::App_Code::Model::DataManager
AspBlog::App_Data::AspBlogEntities
1
Attributes
*
«C# class»
User
Attributes
AspBlog::App_Data::User
1
*
User
1
User
1
Like
*
Blog
*
«C# class»
«C# class»
AspBlog::App_Data::Like
AspBlog::App_Data::Blog
*
Like
*
Blog
1
Entry
1
Entry
*
+ BlogSet : ObjectSet + EntrySet : ObjectSet<Entry> + LikeSet : ObjectSet + UserLog : ObjectSet<UserLog> + UserSet : ObjectSet<User> - _BlogSet : ObjectSet - _EntrySet : ObjectSet<Entry> - _LikeSet : ObjectSet - _UserLog : ObjectSet<UserLog> - _UserSet : ObjectSet<User>
1
* 1
Operations + AddToBlogSet(blog : Blog) + AddToEntrySet(entry : Entry) + AddToLikeSet(like : Like) + AddToUserLog(userLog : UserLog) + AddToUserSet(user : User) + AspBlogEntities() + AspBlogEntities(connectionString : String) + AspBlogEntities(connection : EntityConnec… - OnContextCreated()
«C# class» AspBlog::App_Data::Entry
*
1
1
- m_model : AspBlogEntities - m_strPasswordSalt : String Operations
1
1
+ CreateEntry(data : EntryData, image : Byte[*]) + DeleteEntry(nUserId : Integer, nBlogId : Integ… + HashPassword(strPassword : String, nUserLeng… + LikeEntry(nUserId : Integer, nBlogId : Integer,… + LoadBlogs(nIndex : Integer, nCount : Integer,… + LoadBlogSummary(nBlogID : Integer) : BlogData + LoadBlogSummary(blog : Blog) : BlogData + LoadEntries(nBlogId : Integer, nIndex : Intege… + LoadEntryData(entry : Entry) : EntryData + LoadEntryData(nBlogId : Integer, nEntryId : In… + LoadEntryImage(nBlogId : Integer, nEntryId :… + LoadUser(idCookieSession : Integer) : UserData + LoadUser(strName : String, strPassword : Strin… + LoadUserAvatar(idUser : Integer) : Byte[*] + LoadUserName(idUser : Integer) : String + SaveEntry(data : EntryData, image : Byte[*]) + SaveUser(user : UserData, avatar : Byte[*], str… - static DataManager()
3. ábra. Osztály diagram - Logikai réteg segédosztályok segítségével adjuk tovább (UserData, BlogData, EntryData). A kivételeket speciális formában adjuk tovább. ˝ definiált szöveggel („AspBlog• A felhasználó kezelésnél ügyelünk a jelszó titkosítására, ezért önmagával és egy elore Salt”) megsózzuk, majd SHA1 algoritmussal kódoljuk a jelszót (a felhasználó mentésekor és betöltésekor is).
Felületi réteg: • A felületen 9 oldalt valósítunk meg: nyítóoldal (Default), letöltés (Download), regisztráció (Register), bejelentkezés (Login), kijelentkezés (Logout), blog olvasás (ReadBlog), bejegyzés olvasás (ReadEntry), bejegyzés szerkesztés (WriteEntry), keresés (Search).
˝ • Az oldalakat egy mesteroldalba (ELearning.Master) ágyazzuk, amely tartalmazza a címsávot, a menüt a ki-/bejelentkezo/regis dobozt. A megjelenítési stílusokat a Styles\Site.css fájlban helyezzük el. ˝ • A bejelentkezést követoen a felhasználó adatait munkamenet változóban („User”) tároljuk. • A nyitóoldal jeleníti meg az összes blog listáját. • A blog olvasás oldalon jelenítjük meg egy adott bloghoz tartozó összes bejegyzés listáját. ˝ • A listázó vezérlokhöz (BlogListing, EntryListing) kódban, adatkötéssel társítjuk az adatforrásokat. • A legtöbb oldalon GET paraméterek segítségével továbbítjuk a munkamenet adatait. Ez alól kivételek az urlapok ˝ ˝ gombkezeloi.
4
cd ClassDiagram-View 1
1
«C# class»
«C# class»
«C# class»
«C# class»
AspBlog::Global
AspBlog::_Default
AspBlog::Search
AspBlog::C…BlogListing
Attributes
Attributes
Attributes
Operations
Operations
Operations
# BlogList : ListView
+ Global() - Application_End(sender : O… - Application_Error(sender : O… - Application_Start(sender : O… - Session_End(sender : Objec… - Session_Start(sender : Obje…
+ # # #
+ Search() - TurnPage(nIndex : Integer,… # NextLink_Click(sender : Ob… # Page_Load(sender : Object… # PreviousLink_Click(sender :… # SearchButton_Click(sender… # SearchValidate(source : Ob…
Operations
_Default() NextLink_Click(sender : Ob… Page_Load(sender : Object… PreviousLink_Click(sender :…
Attributes
1
1
+ + + + #
BlogListing() FormatDate(dataItem : Obj… SetData(listBlogs : List
«C# class»
«C# class»
«C# class»
AspBlog::Download
AspBlog::ReadBlog
AspBlog::C…ntryListing
Attributes
Attributes
Operations
Operations
+ Download() # Page_Load(sender : Object… # SendImage(image : Byte[*])
+ # # # #
«C# class» AspBlog::SiteMaster Attributes
ReadBlog() AddEntry_Click(sender : Ob… NextLink_Click(sender : Ob… Page_Load(sender : Object… PreviousLink_Click(sender :…
Operations «C# class» AspBlog::A…t::Register
«C# class»
+ SiteMaster() # Page_Load(sender : Object…
AspBlog::WriteEntry
Attributes
Attributes
Operations
Operations
+ Register() # ButtonRegister_Click(sende… # Page_Load(sender : Object…
+ WriteEntry() # Page_Load(sender : Object… # SubmitButton_Click(sender…
«C# class»
«C# class»
«C# class»
AspBlog::Account::Login
AspBlog::A…nt::Logout
AspBlog::ReadEntry
Attributes
Attributes
Attributes
Operations
Operations
Operations
+ Login() # LoginButton_Click(sender :… # Page_Load(sender : Object…
+ Logout() # Page_Load(sender : Object…
+ # # # #
ReadEntry() DeleteLink_Click(sender : O… EditLink_Click(sender : Obj… LikeLink_Click(sender : Obj… Page_Load(sender : Object…
4. ábra. Osztály diagram - Felületi réteg
5
Attributes # EntryList : ListView 1
1
Operations + + + + #
EntryListing() FormatTime(dataItem : Obj… SetData(listBlogs : List<Ent… WriteText(entryData : Obje… Page_Load(sender : Object…