Univerzitet u Novom Sadu Tehnički fakultet “Mihajlo Pupin” Zrenjanin Diplomski rad Tema: Razvoj višeslojne web aplikacije uz primenu servisno-orijentisane arhitekture Development of n-tier web application with use of service-oriented architecture Mentor: Student: doc. dr Ljubica Kazi Marko Blažić IT 90/15 Zrenjanin, 2017.
74
Embed
Diplomski rad - tfzr.uns.ac.rs · Diplomski rad 6 Proces razvoja softverskih proizvoda, pa tako i Web aplikacija je skup metoda, aktivnosti, prakse i automatizovanih alata koje programeri
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Univerzitet u Novom Sadu
Tehnički fakultet “Mihajlo Pupin”
Zrenjanin
Diplomski rad
Tema: Razvoj višeslojne web aplikacije uz primenu
servisno-orijentisane arhitekture
Development of n-tier web application with use of
service-oriented architecture
Mentor: Student:
doc. dr Ljubica Kazi Marko Blažić IT 90/15
Zrenjanin, 2017.
Diplomski rad
2
Sadržaj
1. UVOD ...............................................................................................Error! Bookmark not defined.
2. TEORIJSKE OSNOVE .........................................................................Error! Bookmark not defined.
2.1. Web aplikacije .........................................................................Error! Bookmark not defined.
naloga, Unos podataka o proizvodima za naručivanje, Unos podataka o plaćanju
Taleba 4.- Prikaz mogućnosti admina i kupca
Slika 35.- Use case dijagram
Diplomski rad
41
6.3 Modeli implementiranog rešenja višeslojne arhitekture softvera
6.3.1 Dijagram komponenti
Dijagram prikazuje strukturne relacije između softverskih komponenti sistema. On ilustruje delove
softvera, ugrađene kontrolere i slično, i ima veći stepen apstrakcije od dijagrama klasa.[26
Dijagram komponenti služi za modeliranje izvornog koda, modeliranje izdanja za isporuku,
modeliranje izvršnih izdanja i okruženja, kao i modeliranje fizičkih baza podataka. Na sledećim
slikama će biti prikazan izgled dijagrama komponenti za našu aplikaciju razvrstanu po slojevima.
Slika 36.- Dijagram komponenti
Diplomski rad
42
Slika 37.- Dijagram komponenti 2. deo
Diplomski rad
43
6.3.2 Dijagram razmeštaja
Dijagram razmeštaja prikazuje statički pogled run-time hardverske konfiguracije i softverskih
komponenti koje se izvršavaju na tim čvorovima. Dijagram razmeštaja prikazuje hardver vašeg
sistema, softver koji je instaliran na tom sistemu i srednji sloj koji se koristi za povezivanje
međusobno razdvojenih mašina.[26]
Slika 38.- Dijagram razmeštaja
Diplomski rad
44
6.3.3 Dijagram klasa
Dijagram klasa nam daje mogućnot pregleda svih klasa unutar svakog sloja pojedinačno kao i
način na koji su klase međusobno povezane.
Slika 39.- Dijagram klasa
Diplomski rad
45
Slika 40.- Dijagram klasa 2 deo
Diplomski rad
46
6.4 Korisničko uputstvo
Prilikom izrade seminarskog rada rađena je aplikacije za online prodaju fitness opreme.
Aplikacije je funkcionalna upostpunosti ali pored toga ima još dosta mesta za usavršavanje. Ova
aplikacija je primer stečenog znanja u pravljenju web apliakcije u programskom jeziku C# i
programu Visual Studio 2015.
Slika 41.- Prikaz početne stranice web sajta
Kad je korisnik ušao na web sajt potrebno je da se uloguje na svoj nalog kako bi bio u
mogućnosti da kupi neku od navedene opreme ili sprave. Korisnik treba da unese šifru i lozinku
svoj profila kako bi se ulogovao. Sledi proces autentifikacije i u koliko se e-mail i lozinka
poklapaju korisnik je ulogovan. Kad je ovo urađeno koisnik može da otvori bilo koju karticu iz
menija.
Diplomski rad
47
Slika 42.- Prikaz kartice sa opremom
Slika 43.- Prikaz kartice sa spravama
Diplomski rad
48
Slika 44.- Prikaz kartice sa ishranom
Sada kad korisnik ima uvid o opremi i spravama koje je u mogućnosti da kupi, kupovinu može
obaviti tako što pritisne na dugme Kupi, aplikacija zatim otvara korpu i dodaje opremu ili spravu
koju kupac želi. Korisnik zatim ima opciju da se vrati nazad i odabere još neku stavku za
kupovinu ili da nastavi sa kupovinom i unese svoje lične podatke.
Slika 45.- Prikaz korpe
Diplomski rad
49
Kad je korisnik odabrao opciju pojavljuju mu se jedna od dva navedena prozora
Slika 46.- Prozor koji se otvara prilikom dugmeta nastavak kupovine
Slika 47.- Prozor koji se javlja kad korisnik pritisne dugme Potvrdi
Nakon ovoga sledi prozor za odabir operatora za dostavu i unos koda za popust. Krajni prozor
izgleda ovako.
Diplomski rad
50
Slika 48.- Prikaz prozora sa završenom kupovinom
Diplomski rad
51
U koliko se ulogujemo kao admin pored navedenim opcija, administrator ima još neke dodatne
povoljnosti kao što su kreiranja nove opreme, marke, tipa marka, sprava i ishrane. Pored ovoga
administrator ima mogućnost rada sa profilima, dodavanja novih, izmena postojećih i brisanje.
Slika 49.- Prikaz prozora kad smo ulogovani kao administrator
Slika 50.- Prikaz prozora podataka o svim spravama kad smo ulogovani kao administrator
Diplomski rad
52
Slika 51.- Prikaz prozora za izmenu
Diplomski rad
53
6.5 Opis implementacije
6.5.1 Plan i opis implementiranih elemenata višeslojne arhitekture
Prilikom izrade bilo je potrebno napraviti bazu podataka sa tabelama koje su vezane za pojmove
koje želimo da prikažemo kao što je oprema, sprave, ishrana i druge stvari koje su bitne za naš
sajt. Da bi baza podataka funkcionisala morali smo da napišemo SQL upite koji se nalaze u sloju
za rad sa bazom podataka. Takođe smo morali kreirati sloj modela koji će sadržati get i set
metodu čija je funkcija prikupljanje podataka i postavljanje u model. Da bi ovo sve funkcionisalo
kako treba moramo koristiti i web servis koji će nam omogućiti komunikaciju između web
aplikacije za onlajn prodaju i dobavljača. Poslednji sloj, prezentacioni sloj prikazuje ono što je
korisnik putem poruka zahtevao od aplikacije. Ovaj sloj komunicira sa ostalim slojevima kako bi
pružio što bolju uslugu korisniku.
SLOJ PODSLOJEVI PLAN IMPLMENTACIJE U
RADU
Prezentacioni sloj Korisnički interfejs Ekranska forma
Prezentaciona logika Kod je prikazan u obliku grafičkih
elemenata, sve aktivnosti su vezane
za klik na dugme
Klase iz View sloja
Sloj servisa Web servis Pristup podacima od dobavljača
Biblioteka klasa
servisa za mapiranje
Mapiranje između slojeva
Sloj poslovne logike i modela Poslovni objekti Korpa, dostava
Poslovna pravila Popust
Sloj za rad sa bazom podataka Biblioteke klasa za rad
sa bazom podataka
Klase repository
Klase modela
Baze podataka i
DBMS
Tabele i relacije baze podataka
U nastavku će biti opisani elementi implementacije po slojevima počevši od baze podataka ka
višim slojevima. Implementacija softverskog koda je realizovana na osnovu primera koji je rađen
u okviru vežbi iz predmeta Sofversko inženjerstvo 2.
Diplomski rad
54
6.5.2 SQL Script i šema baze podataka
U diplomskom radu smo koristili bazu podataka koju nam nudi program Visual Studio, međutim
bilo je porebno još instalirati podršku u vidu SQL server data tools-a kako bi svaka fukincija
radila kako treba. U nastavku ćemo prikazati spisak svih tabela unutar baze podataka:
CREATE TABLE [dbo].[T_MARKA] ( [MarkaId] INT IDENTITY (1, 1) NOT NULL, [Ime] NVARCHAR (50) NOT NULL, PRIMARY KEY CLUSTERED ([MarkaId] ASC) );
CREATE TABLE [dbo].[T_TIP] ( [TipId] INT IDENTITY (1, 1) NOT NULL, [Ime] NVARCHAR (50) NOT NULL, PRIMARY KEY CLUSTERED ([TipId] ASC) );
CREATE TABLE [dbo].[T_ISHRANA] ( [IshranaId] INT IDENTITY (1, 1) NOT NULL, [Ime] NVARCHAR (50) NOT NULL, [Opis] NVARCHAR (MAX) NOT NULL, [VelicinaObroka] NVARCHAR (50) NOT NULL, [TipId] INT NOT NULL, [ImageData] VARBINARY (MAX) NOT NULL, [ImageMimeType] NVARCHAR (50) NOT NULL, PRIMARY KEY CLUSTERED ([IshranaId] ASC), CONSTRAINT [fk_T_ISHRANA_T_TIP] FOREIGN KEY ([TipId]) REFERENCES [dbo].[T_TIP] ([TipId]) ); CREATE TABLE [dbo].[T_ISHRANA_IMAGE] ( [IshranaId] INT NOT NULL, [ImageData] VARBINARY (MAX) NOT NULL, [ImageMimeType] NVARCHAR (50) NOT NULL ); CREATE TABLE [dbo].[T_OPREMA] ( [OpremaId] INT IDENTITY (1, 1) NOT NULL, [Ime] NVARCHAR (50) NOT NULL, [Opis] NVARCHAR (MAX) NOT NULL, [Cena] DECIMAL (8, 2) NOT NULL, [Boja] NVARCHAR (50) NOT NULL, [Velicina] NVARCHAR (20) NOT NULL, [MarkaId] INT NOT NULL, [TipId] INT NOT NULL, [ImageData] VARBINARY (MAX) NOT NULL, [ImageMimeType] NVARCHAR (50) NOT NULL, PRIMARY KEY CLUSTERED ([OpremaId] ASC), CONSTRAINT [fk_T_OPREMA_T_MARKA] FOREIGN KEY ([MarkaId]) REFERENCES [dbo].[T_MARKA] ([MarkaId]),
Diplomski rad
55
CONSTRAINT [fk_T_OPREMA_T_TIP] FOREIGN KEY ([TipId]) REFERENCES [dbo].[T_TIP] ([TipId]) ); CREATE TABLE [dbo].[T_OPREMA_IMAGE] ( [OpremaId] INT NOT NULL, [ImageData] VARBINARY (MAX) NOT NULL, [ImageMimeType] NVARCHAR (50) NOT NULL ); CREATE TABLE [dbo].[T_SPRAVA] ( [SpravaId] INT IDENTITY (1, 1) NOT NULL, [Ime] NVARCHAR (50) NOT NULL, [Opis] NVARCHAR (MAX) NOT NULL, [Cena] DECIMAL(2, 8) NOT NULL, [Velicina] NVARCHAR (20) NOT NULL, [MarkaId] INT NOT NULL, [TipId] INT NOT NULL, [ImageData] VARBINARY (MAX) NOT NULL, [ImageMimeType] NVARCHAR (50) NOT NULL, PRIMARY KEY CLUSTERED ([SpravaId] ASC), CONSTRAINT [Fk_T_SPRAVA_T_MARKA] FOREIGN KEY ([MarkaId]) REFERENCES [dbo].[T_MARKA] ([MarkaId]), CONSTRAINT [Fk_T_SPRAVA_T_TIP] FOREIGN KEY ([TipId]) REFERENCES [dbo].[T_TIP] ([TipId]) ); CREATE TABLE [dbo].[T_SPRAVA_IMAGE] ( [SpravaId] INT NOT NULL, [ImageData] VARBINARY (MAX) NOT NULL, [ImageMimeType] NVARCHAR (50) NOT NULL ); CREATE TABLE [dbo].[T_KORISNIK] ( [KorisnikId] UNIQUEIDENTIFIER NOT NULL, [Ime] NVARCHAR (50) NOT NULL, [Šifra] NVARCHAR (50) NOT NULL, [Email] NVARCHAR (50) NOT NULL, [Uloga] NVARCHAR (20) NOT NULL, PRIMARY KEY CLUSTERED ([KorisnikId] ASC) );
Listing 1.- kod unutar tabela baze podataka
Diplomski rad
56
6.5.3 Ključni delovi koda sa objašnjenjem
6.5.2.1. Klase modela
Klase modela su generisane na osnovu baze podataka korišćenjem Entity Framework. Unutar
ovog sloja se nalaze klase koje su slične kao tabele u bazi podataka, tako da imaju privatne i
javne atribute sličnog naziva kao polja u tabelama, sa get i set metodama.
using Fitness.Oprema.Model.Entities.Marka; using Fitness.Oprema.Model.Entities.Tip; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Fitness.Oprema.Model.Entities.Sprave { public class Sprava { public int SpravaId { get; set; } public string Ime { get; set; } public string Opis { get; set; } public string Velicina { get; set; } public decimal Cena { get; set; } public Marka Marka { get; set; } public Tip Tip { get; set; } public SpravaImage SpravaImage { get; set; } public List<SpravaImage> SpravaImages { get; set; } } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Softversko2.Oprema.Model.Entities.Sprave { public class SpravaImage { public byte[] ImageData { get; set; } public string ImageMimeType { get; set; } } }
Listing 2.- Kod koji se nalazi unutar sloja Model
Diplomski rad
57
6.5.2.2. Klase repository
Klase ovog sloja sadrže mehanizme za aktivan rad sa bazom podataka kroz konekciju, SQL upite
i slično.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Fitness.Oprema.Model.Entities.Sprave { public interface ISpravaRepository { List<Sprava> ReadAll(); void Update(Sprava entity); void Create(Sprava entity); void Delete(int id); } }
using Fitness.Oprema.Model.Entities.Marka; using Fitness.Oprema.Model.Entities.TIp; using Fitness.Oprema.Model.Entities.Sprave; using System; using System.Collections.Generic; using System.Configuration; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Fitness.Oprema.Repository.Sprave { public class SpravaRepository : ISpravaRepository { private string _connectionString; public SpravaRepository() { _connectionString = ConfigurationManager.ConnectionStrings["OpremaConnectionString"].ConnectionString; } public List<Sprava> ReadAll() { List<Sprava> sprave = new List<Sprava>(); string queryStringSprava = "SELECT p.SpravaId, p.Ime, p.Opis, p.Velicina, p.Cena , p.ImageData, p.ImageMimeType, " + " b.MarkaId, b.Ime, " + " c.TipId, c.Ime " +
Diplomski rad
58
"FROM dbo.T_SPRAVA p, dbo.T_Marka b, dbo.T_Tip c " + "WHERE p.MarkaId = b.MarkaId AND p.TipId = c.TipId"; string queryStringSpravaImages = "SELECT SpravaId, ImageData, ImageMimeType FROM dbo.T_SPRAVA_IMAGE WHERE SpravaId = @SpravaId"; using (SqlConnection connection = new SqlConnection(_connectionString)) { SqlCommand command = connection.CreateCommand(); command.CommandText = queryStringSprava; connection.Open(); using (SqlDataReader reader = command.ExecuteReader()) { Sprava sprava; while (reader.Read()) { sprava = new Sprava(); sprava.SpravaId = Int32.Parse(reader[0].ToString()); sprava.Ime = reader[1].ToString(); sprava.Opis= reader[2].ToString(); sprava.Velicina = reader[3].ToString(); sprava.Cena = Decimal.Parse(reader[4].ToString()); sprava.SpravaImage = new SpravaImage(); sprava.SpravaImage.ImageData = string.IsNullOrEmpty(reader[5].ToString()) ? null : (byte[])reader[5]; sprava.SpravaImage.ImageMimeType = reader[6].ToString(); sprava.Marka = new Oprema(); sprava.Marka.MarkaId = Int32.Parse(reader[7].ToString()); sprava.Marka.Ime = reader[8].ToString(); sprava.Tip = new Tip(); sprava.Tip.TipId = Int32.Parse(reader[9].ToString()); sprava.Tip.Ime = reader[10].ToString(); sprave.Add(sprava); } } foreach (Sprava sprava in sprave) { sprava.SpravaImages = new List<SpravaImage>(); SqlCommand commandSpravaImage = connection.CreateCommand(); commandSpravaImage.CommandText = queryStringSpravaImages; commandSpravaImage.Parameters.Add(new SqlParameter("@SpravaId", sprava.SpravaId)); using (SqlDataReader reader = commandSpravaImage.ExecuteReader()) { while (reader.Read()) { SpravaImage spravaImage = new SpravaImage(); spravaImage.ImageData = (byte[])reader[1]; spravaImage.ImageMimeType = reader[2].ToString(); sprava.SpravaImages.Add(spravaImage); }
Listing3.- Prikaz koda u sloju za upravljanje bazom podataka
6.5.2.3. Klasa poslovnih pravila
Klase ovog sloja sadrže poslovna pravila i matematičke metode kojima se određuje popust nekog
proizvoda.
namespace Fitness.Oprema.Model.Entities.Korpa { public class Popust : IPopust { public decimal GetTotalCostAfterApplyingDiscountTo(Popust popust) { if (popust.ComputeTotalValue() > 5000) return popust.ComputeTotalValue() - 500m; if (popust.ComputeTotalValue() > 2000) return popust.ComputeTotalValue() - 200m; else return popust.ComputeTotalValue(); } } }
Listing 4.- Kod unutar klase Popust
Diplomski rad
62
6.5.2.4. Klasa poslovnih objekta
Unutar ovog sloja nalaze se klase sa klase koja se koristi za korpu i klasa operatera dobavljača.
using Fitness.Oprema.Model.Entities.Oprema; using System.Collections.Generic; using System.Linq; namespace Fitness.Oprema.Model.Entities.Korpa { public class Popust { private List<PopustLine> lineCollection = new List<PopustLine>(); private IPoputStrategija Popust; public void SetPopustStrategiju(string discountType) { Popust = PopustFaktor.GetDiscount(discountType); } public void AddItem(Oprema oprema, int quantity) { PopustLine line = lineCollection .Where(p => p.Oprema.OpremaId == oprema.OpremaId) .FirstOrDefault(); if (line == null) { lineCollection.Add(new PopustLine { Oprema = oprema, Quantity = quantity }); } else { line.Quantity += quantity; } } public void RemoveLine(Oprema oprema) { lineCollection.RemoveAll(l => l.Oprema.OpremaId == oprema.OpremaId); } public decimal ComputeTotalValue() { return lineCollection.Sum(e => e.Oprema.Price * e.Quantity); } public decimal ComputeTotalValueAfterPopust() { return Popust.GetTotalCostAfterApplyingPopustTo(this);
Diplomski rad
63
} public void Clear() { lineCollection.Clear(); } public IEnumerable<Popust> get { return lineCollection; } } } public class PopustLine { public Oprema Oprema { get; set; } public int Quantity { get; set; } } }
Listing 5.- Kod unutar klase Korpa
namespace Fitness.Oprema.Model.Entities.Dostava { public class AksDelivery : IDostavaOperator { public decimal getDeliveryPrice() { return 250; } public string getDeliveryTime() { return "3 radna dana"; } } }
namespace Fitness.Oprema.Model.Entities.Dostava { public class BexDelivery : IDostavaOperator { public decimal getDeliveryPrice() { return 300M; } public string getDeliveryTime() { return "2 radna dana"; } } } namespace Fitness.Oprema.Model.Entities.Dostava
Diplomski rad
64
{ public static class DostavaFaktor { public static IDostavaOperator CreateDeliveryOperator(string operatorName) { if (operatorName == "Aks") return new AksDelivery(); else return new BexDelivery(); } } } namespace Fitness.Oprema.Model.Entities.Dostava { public interface IDostavaOperator { decimal getDeliveryPrice(); string getDeliveryTime(); } }
namespace Fitness.Oprema.Model.Entities.Dostava { public class DostavaDetails { public string Address { get; set; } public string City { get; set; } public string Zip { get; set; } public string Country { get; set; } } }
Listing 6.- Kod unutar klase shipping
6.5.2.5. Biblioteka klasa servisa za mapiranje
Kod unutar klase služi za transformaciju poruka između prezentacionog sloja i sloja modela.
using Fitness.Oprema.AppService.Messages.Sprave; using Fitness.Oprema.Model.Entities.Marka; using Fitness.Oprema.Model.Entities.Tip; using Fitness.Oprema.Model.Entities.Sprave; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Fitness.Oprema.AppService.Mappings.Sprave { public static class SpravaMapper { public static Sprava ConvertToSprava(this CreateSpravaRequest createRequest) {
Diplomski rad
65
Sprava sprava = new Sprava(); sprava.Ime = createRequest.Ime; sprava.Opis = createRequest.Opis; sprava.Velicina = createRequest.Velicina; sprava.Marka = new Marka() { MarkaId = createRequest.MarkaId }; sprava.Tip = new Tip() { TipId = createRequest.TipId }; sprava.SpravaImage = createRequest.SpravaImage; sprava.SpravaImages = createRequest.SpravaImages; return sprava; } public static Sprava ConvertToSprava(this UpdateSpravaRequest updateRequest) { Sprava sprava = new Sprava(); sprava.SpravaId = updateRequest.SpravaId; sprava.Ime = updateRequest.Ime; sprava.Opis = updateRequest.Opis; sprava.Velicina = updateRequest.Velicina; sprava.Marka = new Marka() { MarkaId = updateRequest.MarkaId }; sprava.Tip = new Tip() { TipId = updateRequest.TipId }; sprava.SpravaImage = updateRequest.SpravaImage; sprava.SpravaImages = updateRequest.SpravaImages; return sprava; } } }
Listing 7.- Kod unutar klase Sprav.Mapper
6.5.2.6. Klase web servisa
Unutar ovih klasa se na nalazi kod koji nam daje mogućnost da se povežemo sa URL-om
dobavljača, kako bismo omogućili on-line usklađivanje podataka o robi sa web aplikacijom za
prodaju proizvoda.
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services; using System.Data; namespace WebService1 { /// <summary> /// Summary description for Service1 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment
Diplomski rad
66
the following line. // [System.Web.Script.Services.ScriptService] public class Service1 : System.Web.Services.WebService { // procedura koja na osnovu naziva robe vraca naziv proizvodjaca [WebMethod] public string DajNazivProizvodjaca(string NazivRobe) { string NazivProizvodjaca = ""; DataSet dsProizvodjaci = new DataSet(); dsProizvodjaci.ReadXml(Server.MapPath("~/") + "XML/Proizvodjaci.XML"); // filtriranje dataset-a DataRow[] result = dsProizvodjaci.Tables[0].Select("NazivRobe='" + NazivRobe + "'"); NazivProizvodjaca = result[0].ItemArray[0].ToString(); return NazivProizvodjaca; } // procedura koja na osnovu naziva robe vraca CENU ROBE [WebMethod] public string DajCenuRobe(string NazivRobe) { string CenaRobe = ""; DataSet dsProizvodjaci = new DataSet(); dsProizvodjaci.ReadXml(Server.MapPath("~/") + "XML/Roba.XML"); // filtriranje dataset-a DataRow[] result = dsProizvodjaci.Tables[0].Select("NazivRobe='" + NazivRobe + "'"); CenaRobe = result[0].ItemArray[2].ToString(); return CenaRobe; } // procedura koja vraca detaset sa nazivima robe [WebMethod] public DataSet DajDataSetNazivaRoba() { DataSet dsProizvodjaci = new DataSet(); dsProizvodjaci.ReadXml(Server.MapPath("~/") + "XML/Roba.XML"); return dsProizvodjaci; } [WebMethod] public DataSet DajDataSetNazivaProizvodjaca () { DataSet dsProizvodjaci = new DataSet(); dsProizvodjaci.ReadXml(Server.MapPath("~/") + "XML/Proizvodjaci.XML"); return dsProizvodjaci; }
Listing 8.- Kod unutar klase WebServise1
Diplomski rad
67
6.5.2.7. Mogućnost poziva web servisa u okviru aplikacije
Web servis je zapravo on-line bibliteka klasa i koristi se putem aliasa koji se daje za URL dalje
kao da je naziv biblioteke klasa. Nadalje, instanciramo objekat klase iz web servisa i koristimo
metode. U nastavku je dat kod koji prikazuje metodu ReadAll iz sloja Repository za sprave.
public List<Sprava> ReadAll() { List<Sprava> sprave = new List<Sprava>(); string queryStringSprava = "SELECT p.SpravaId, p.Ime, p.Opis, p.Velicina , p.ImageData, p.ImageMimeType, " + " b.MarkaId, b.Ime, " + " c.TipId, c.Ime " + "FROM dbo.T_SPRAVA p, dbo.T_MARKA b, dbo.T_TIP c " + "WHERE p. MarkaId = b. MarkaId AND p.TipId = c.TipId "; string queryStringSpravaImages = "SELECT SpravaId, ImageData, ImageMimeType FROM dbo.T_SPRAVA_IMAGE WHERE SpravaId = @SpravaId"; using (SqlConnection connection = new SqlConnection(_connectionString)) { SqlCommand command = connection.CreateCommand(); command.CommandText = queryStringSprava; connection.Open(); using (SqlDataReader reader = command.ExecuteReader()) { Sprava sprava; while (reader.Read()) { sprava = new Sprava(); sprava.SpravaId = Int32.Parse(reader[0].ToString()); sprava.Ime = reader[1].ToString(); sprava.Opis= reader[2].ToString(); sprava.Velicina = reader[3].ToString(); sprava.SpravaImage = new SpravaImage(); sprava.SpravaImage.ImageData = string.IsNullOrEmpty(reader[4].ToString()) ? null : (byte[])reader[4]; sprava.SpravaImage.ImageMimeType = reader[5].ToString(); sprava.Marka = new Marka(); sprava.Marka.MarkaId = Int32.Parse(reader[6].ToString()); sprava.Marka.Ime = reader[7].ToString(); sprava.Tip = new Tip(); sprava.Tip.TipId = Int32.Parse(reader[8].ToString()); sprava.Tip.Ime = reader[9].ToString(); sprave.Add(sprava); } } foreach (Sprava sprava in sprave)
Listing 9.- prikaz koda unutra klase Sprava u repoitory sloju
Izmenjeni kod kojim se prikazuje mogućnost poziva web servisa za preuzimanje podataka,
umesto iz baze podataka, dat je u nastavku.
U projektu smo dodali „Service reference“ i URL-u web servisa dodelili naziv, tj. Alias.
Slika 52. Izgled solution explorera nakon dodavanja web servisa
Diplomski rad
69
U programskom kodu, pozivanje i korišćenje web servisa prikazano je u nastavku:
public List<Proizvodjac> ReadAll() { List<Proizvodjac> proizvodjac = new List< Proizvodjac >(); // Pozivanje web servisa koji obezbedjuje podatke VebServis.Service1 objVebServis = new VebServis.Service1(); System.Data.DataSet dsProizvodjaci = objVebServis.DajDataSetNazivaProizvodjaca (); Int brojzapisa = dsProizvodjaci.Tables[0].Rows.Count;
Proizvodjac objProizvodjac; For (i=0; i<=brojzapisa; i++) { objProizvodjac = new Proizvodjac (); sprava.ProizvodjacId = Int32.Parse(reader[0].ToString()); sprava.Ime = reader[1].ToString(); sprave.Add(sprava); }
Listing 10.- Prikaz koda koji se implementira za web servis
Kolekcija objekata klase Proizvodjac u formi liste je spremna za koriscenje kod punjenja combo
boxa npr. na formi za unos nove robe.
6.5.2.8. Klase i html pogledi unutar prezentacionog sloja
Unutar ovog sloja se nalaze klase koje nam omogućavaju prikaz podataka koje korisnik putem
poruka zahteva od aplikacije. Takođe, date su i klase kontrolera i html osnova pogleda.
Model klasa sadrži objekte istoimene klase unutar model sloja sa get i set metodom. Kontroler
zatim preuzima vrednosti iz datog modela na zahtev korisnika i šalje podatke pogledu koji ih
ispisuje.
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace Fitness.EStore.Web.Areas.Products.Models { public class AllSpravePageViewModel { public List<SpravaViewModel> SpravaViewModels { get; set; } public bool Success { get; set; } public string ErrorMessage { get; set; } } }
Listing 11.-Kod unutar klase Model
Diplomski rad
70
using Fitness.Oprema.AppService.Abstractions.Sprave; using Fitness.Oprema.AppService.Messages.Sprave; using Fitness.Oprema.Model.Entities.Sprave; using Fitness.Oprema..Web.Areas.Products.Models; using Fitness.Oprema.Web.Mappings.Sprave; using Fitness.Oprema.Web.Models.Sprave; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Fitness.Oprema.Web.Areas.Products.Controllers { public class SpravaController : Controller { private ISpravaService spravaService; public SpravaController(ISpravaService spravaService) { this.spravaService = spravaService; } // GET: Products/Product public ActionResult Index() { FindAllSpraveResponse response = new FindAllSpraveResponse(); response = spravaService.FindAllSprave(); AllSpravePageViewModel model = new AllSpravePageViewModel(); model.SpravaViewModels = response.Sprave.ConvertToSpravaViewModelList(); model.Success = response.Success; model.ErrorMessage = response.Message; return View(model); } public FileContentResult GetImage(int spravaId) { SpravaViewModel spravaViewModel = spravaService.FindAllSprave().Sprave. Find(x => x.SpravaId == spravaId).ConvertToSpravaViewModel(); if (spravaViewModel != null) { return File(spravaViewModel.SpravaImageViewModel.ImageData, spravaViewModel.SpravaImageViewModel.ImageMimeType); } else { return null; }}}}